OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9213|回复: 22

问大家关于一个C语言的问题,关于#if,#elif

[复制链接]

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
发表于 2019-12-12 14:28:36 | 显示全部楼层 |阅读模式
50金钱
#define   OUTPUTMODE    OUTPUT_YCBCR422_16BIT
#if (OUTPUTMODE == OUTPUT_RGB888)
    {               

                if(OUTPUTMODE == OUTPUT_YCBCR422_16BIT)
                {                               
                        printf("OK\r\n");
                }
                else
                {
                printf("error\r\n");
                }

    }
    #endif
我的问题是,为什么printf("OK\r\n");  这一句代码,会执行?我用的keli编译。


最佳答案

查看完整内容[请看2#楼]

#if 是虚拟指令, 他不认enum的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4105
金钱
4105
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-12-12 14:28:37 | 显示全部楼层
#if 是虚拟指令, 他不认enum的
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-12-12
在线时间
5 小时
发表于 2019-12-12 14:56:14 | 显示全部楼层
宏OUTPUT_YCBCR422_16BIT是否和宏OUTPUT_RGB888定义成一样的值了??
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-12 15:03:40 | 显示全部楼层
superlei1003 发表于 2019-12-12 14:56
宏OUTPUT_YCBCR422_16BIT是否和宏OUTPUT_RGB888定义成一样的值了??

两个值都是typedef下的枚举类型  打印出来看了,两个值不一样
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2019-12-12 15:11:33 | 显示全部楼层
打次 发表于 2019-12-12 15:03
两个值都是typedef下的枚举类型  打印出来看了,两个值不一样

不可能,,,肯定是你错了
https://github.com/WZTENG
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2019-12-12 15:12:15 | 显示全部楼层
打次 发表于 2019-12-12 15:03
两个值都是typedef下的枚举类型  打印出来看了,两个值不一样

把那2个宏定义也放出来
https://github.com/WZTENG
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-12 16:26:51 | 显示全部楼层
WZTENG 发表于 2019-12-12 15:12
把那2个宏定义也放出来

typedef enum
{
    OUTPUT_RGB888,
    OUTPUT_RGB666,
    OUTPUT_RGB565,
    OUTPUT_YCBCR444,
    OUTPUT_YCBCR422_16BIT,
    OUTPUT_YCBCR422_20BIT,
    OUTPUT_YCBCR422_24BIT,
    OUTPUT_BT656_8BIT,
    OUTPUT_BT656_10BIT,
    OUTPUT_BT656_12BIT,
    OUTPUT_BT1120_16BIT,
    OUTPUT_BT1120_20BIT,
    OUTPUT_BT1120_24BIT,
    OUTPUT_LVDS_1_PORT,
    OUTPUT_LVDS_2_PORT
}
_OUTPUTMODE;
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-12 16:29:28 | 显示全部楼层
WZTENG 发表于 2019-12-12 15:12
把那2个宏定义也放出来

其实按照这种定义,两个值分别为0和4,不一样的,应该没问题
回复

使用道具 举报

5

主题

424

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1020
金钱
1020
注册时间
2014-9-4
在线时间
199 小时
发表于 2019-12-12 17:04:21 | 显示全部楼层
打次 发表于 2019-12-12 16:29
其实按照这种定义,两个值分别为0和4,不一样的,应该没问题

枚举不是研究的很深,从结果来看应该是在预编译时,枚举的所有值都是0,,导致#if为真。到运行时(或编译后)枚举的值才确定。
https://github.com/WZTENG
回复

使用道具 举报

9

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2018-8-8
在线时间
50 小时
发表于 2019-12-12 18:26:09 | 显示全部楼层
预编译#if的时候,枚举还没开始编译吧,你试试改成if是不是就不会打印了
回复

使用道具 举报

8

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
292
金钱
292
注册时间
2018-8-14
在线时间
37 小时
发表于 2019-12-12 18:55:47 | 显示全部楼层
是不是编译器优化的问题,你加这个关键字试试   volatile
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-12 18:58:27 | 显示全部楼层
走投无路的卡卡 发表于 2019-12-12 18:26
预编译#if的时候,枚举还没开始编译吧,你试试改成if是不是就不会打印了

if那是肯定可以,不过我可以借鉴一下您的思路,好像确实有可能预编译的时候没有只想到枚举
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-12 18:58:47 | 显示全部楼层
WZTENG 发表于 2019-12-12 17:04
枚举不是研究的很深,从结果来看应该是在预编译时,枚举的所有值都是0,,导致#if为真。到运行时(或编译 ...

多谢,这个思路我觉得很有帮助
回复

使用道具 举报

7

主题

101

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2017-9-16
在线时间
80 小时
发表于 2019-12-12 20:35:15 | 显示全部楼层
根据C语言预处理器 条件求值 的行为
#if, #elif
表达式 是常量表达式,仅使用常量和用 #define 指令定义的标识符。任何非常量,未以 #define 指令定义的标识符,求值为0。

表达式可以含有形式为 defined 标识符 或 defined (标识符) 的一元运算符,若用 #define 指令定义了该 标识符 ,则返回 1 ,否则返回 0 。若 表达式 求值为非零值,则包含该控制代码块并跳过其他。若所用的任何标识符不是常量,则用 ​0​ 替换它。

如果你未曾给预处理器定义过 OUTPUT_RGB888 标识符 其求值结果为0,#if内部的表达式等价为
  1. OUTPUTMODE ==0
复制代码

参考 条件包含
回复

使用道具 举报

15

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-9-28
在线时间
43 小时
发表于 2019-12-12 21:36:45 | 显示全部楼层
兄啊,你这头像。。。
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-13 14:58:55 | 显示全部楼层
ISO14882 发表于 2019-12-12 20:35
根据C语言预处理器 条件求值 的行为

如果你未曾给预处理器定义过 OUTPUT_RGB888 标识符 其求值结果为0, ...

我打印出来看了 rgb是0,ycbcr是4
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-13 15:21:59 | 显示全部楼层
maxzero 发表于 2019-12-12 21:36
兄啊,你这头像。。。

奥里给
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-5-29
在线时间
28 小时
发表于 2019-12-14 15:28:19 | 显示全部楼层
狗粉丝,给爷爪巴
回复

使用道具 举报

17

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2018-12-28
在线时间
39 小时
 楼主| 发表于 2019-12-15 14:08:25 | 显示全部楼层
edmund1234 发表于 2019-12-12 14:28
#if 是虚拟指令, 他不认enum的

我试过了 不用enum 直接define 也是不行的,但已知再stm8下可以正常执行,在keil的stm32下就无法正常执行
回复

使用道具 举报

6

主题

211

帖子

0

精华

高级会员

Rank: 4

积分
833
金钱
833
注册时间
2019-12-17
在线时间
157 小时
发表于 2020-4-14 15:44:30 | 显示全部楼层
打次 发表于 2019-12-15 14:08
我试过了 不用enum 直接define 也是不行的,但已知再stm8下可以正常执行,在keil的stm32下就无法正常执行
#define    OUTPUT_RGB888   0
#define    OUTPUT_YCBCR422_16BIT     4
#define   OUTPUTMODE    OUTPUT_YCBCR422_16BIT
#if (OUTPUTMODE == OUTPUT_RGB888)
    {               

                if(OUTPUTMODE == OUTPUT_YCBCR422_16BIT)
                {                              
                        printf("OK\r\n");
                }
                else
                {
                printf("error\r\n");
                }

    }
    #endif
你用上面的代码他还会执行吗?

回复

使用道具 举报

19

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
323
金钱
323
注册时间
2016-8-9
在线时间
41 小时
发表于 2021-8-17 16:29:18 | 显示全部楼层
遇到同样的问题,哎,真是闹心!
回复

使用道具 举报

16

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2019-10-24
在线时间
153 小时
发表于 2021-8-18 14:38:44 | 显示全部楼层
#if是编译器在编译代码时完成的,if是在程序运行时进行的在程序运行时执行:
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 06:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表