2014-01-23 42 views
5

下面给出C文件:的#ifdef和之间的#if用于宏定义为微妙差异0

$ cat macros.c 
#ifdef MACRO 
# error MACRO is defined 
#else 
# error MACRO is undefined 
#endif 
#if MACRO 
# error MACRO is non-zero 
#else 
# error MACRO is zero 
#endif 

什么是以下的预期输出?

$ gcc   -c macros.c 
$ gcc -DMACRO -c macros.c 
$ gcc -DMACRO=0 -c macros.c 

:这里是海湾合作委员会在我的机器上的预处理程序所做的。

$ gcc   -c macros.c 
macros.c:4:4: error: #error MACRO is undefined 
macros.c:9:4: error: #error MACRO is zero 
$ gcc -DMACRO -c macros.c 
macros.c:2:4: error: #error MACRO is defined 
macros.c:7:4: error: #error MACRO is non-zero 
$ gcc -DMACRO=0 -c macros.c 
macros.c:2:4: error: #error MACRO is defined 
macros.c:9:4: error: #error MACRO is zero 
$ 

#ifdef MACRO评估为真用于定义岬即使定义的值是0(零)

另一个C预处理器gotcha!这是应该如何按照C标准?

+2

我争辩说,区别是特别“微妙”,也没有任何形式的“陷阱”。这对我来说似乎相当清楚和直观。 '#ifdef'代表“if defined”。你为什么认为这个价值与它有什么关系?也许来自PHP/Javascript惰性比较? –

+1

定义一个具有值'0',或'fred'或'“”'或其他任何东西的宏,实际上仍然定义了这个宏,因此我认为'#ifdef'应该报告宏是定义它是否已被定义 - 它并不在意它定义的值是什么,只是它已被定义... – twalberg

+0

你可以通过阅读标准来回答你的问题;你为什么要求其他人为你阅读? –

回答

2

行为符合标准。

C99标准:6.10.1条件包含:

第2段:预处理的形式

​​

检查控制常量表达式是否评估为非零指令。

第4段:的形式预处理指令标识符

# ifdef identifier new-line groupopt 
# ifndef identifier new-line groupopt 

检查是否是或不是目前定义为宏名称。它们的 条件分别相当于#if defined标识符#if !defined标识符

+2

这并不回答如何在'#if'语句表达式中评估未定义标识符的问题。 –

+0

阅读上面的答案或C标准。 Google for N1570下载该标准的最新免费草案。 – gnasher729

5

#ifdef只关心MACRO是否已被定义。价值并不重要。

#if检查MACRO的值并相应地评估MACRO。

这是正确的行为

+2

这并不回答如何在'#if'语句中的表达式中评估未定义标识符的问题。 –

+1

这在C和C++标准中明确定义 - 在#if或#elif语句中,未将#definition作为宏的标识符替换为0。这应该是常识。 – gnasher729

+0

我可以确认当符号未定义时'#fif'的行为与使用'0'值定义相同。 – micnguyen

6

,因为它被用于评估#if语句控制表达式的目的定义为0的任何未定义的宏处理。从C99§6.10.1/ 3-4(强调):

3)预处理的形式指示

# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt

检查是否控制常量表达式评估为非零。

4)之前的评价,在预处理标记,这将成为 控制常量表达式列表宏调用被替换(除了那些宏名称由defined元运算符改性 ),就如同在普通文本。如果令牌defined为 由于此替换过程而生成或使用defined一元运算符 与宏替换之前的两个指定表格中的一个不匹配,则行为为 未定义。 由于宏观膨胀和defined一元 操作者所有替换之后已经执行了所有剩余的标识符(包括那些词法 相同的关键字)与PP-数0替换,然后将每个预处理 标记转换成一个令牌。 [...]

因此,举例来说,像这样的表达式:

#if !FOO 

将评估为1如果FOO是不确定的,因为这将作为0来处理,然后!FOO会评估为!0,这是1

相关问题