在C语言中使用#define但不赋值的方法

14

如果使用#define而不带有值,例如

#define COMMAND_SPI()

默认情况下它会取值0吗?


3
什么阻止了您自己运行预处理器并查看发生了什么? - Kerrek SB
请注意,您定义了一个类似函数的宏,这意味着除非在COMMAND_SPI后面跟着带括号的参数列表,否则它不会被展开。 - Keith Thompson
2
@KerrekSB 一个系统在一个测试用例中的行为并不能保证所有系统都表现相同(甚至同一代码在同一系统上重新运行时也可能表现不同) - M.M
另一方面,即使观察到一个符合系统没有用0替换宏,也会立即摧毁OP的假设。 - Kerrek SB
1个回答

20
不,它的值为空。这个符号字面上被替换为“nothing”(无)。
但是,一旦你定义了#define FOO,预处理器条件语句#ifdef FOO就会变为真。
还要注意,在gcc和可能其他编译器中,如果你在命令行上用-DFOO定义了一个宏,那么默认情况下它将计算为1
由于原帖现在引用了函数式宏,我们来考虑一个小例子。
#define FOO
#define BAR()


FOO
BAR
BAR()

这不是一个合法的C程序,但是预处理器并不在乎。 如果我用gcc -E 输入.c编译它,我将得到一个空白,接着是BAR,然后又是一个空白。这是因为第一个和第三个表达式都没有结果,而中间的表达式没有被展开,因为它后面没有()


1
最后一段是特定于编译器的;gcc会以那种方式运行,但它并没有被语言规定。对于gcc和类似的编译器,您可以通过在命令行上传递-DFOO =来执行等效于#define FOO的操作。 - Keith Thompson
@KeithThompson,谢谢你的警告。我会将其纳入答案中。 - merlin2011
1
请注意,POSIX要求c99提供-D行为:-D name[=value]将name定义为C语言#define指令一样。如果没有给出= value,则使用值1。-D选项的优先级低于-U选项。也就是说,如果在-U-D选项中都使用了name,则无论选项的顺序如何,name都将被未定义。编译器可以提供其他实现定义的名称。实现必须支持至少2048字节的-D定义和256个名称。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接