我们可以使用“#elif!”在c?

时间:2013-12-22 11:45:42

标签: c gcc

我对sprng2.0中的代码感到困惑,它在我制作之后给了我机器上的编译错误。我的编译器(gcc 4.7.3)似乎不支持#elif !#elif !是什么意思?或者我可以用#ifndef替换它吗?

#ifdef SYNC
if(expJ[dE]>sprng(genptr[k]))
#elif !SYNC
if(dE<=0 || expJ[dE]>sprng(genptr[k]))
#endif

错误讯息为error: operator '!' has no right operand 我已经测试了,

#ifdef SYNC
if(expJ[dE]>sprng(genptr[k]))
#elif !(SYNC)
if(dE<=0 || expJ[dE]>sprng(genptr[k]))
#endif

它给了我错误:missing expression between '(' and ')'

3 个答案:

答案 0 :(得分:5)

您问题中的代码:

#ifdef SYNC
/* ... */
#elif !SYNC
/* ... */
#endif

可能有效也可能无效。如果宏SYNC被定义为空(未定义,但定义为扩展为无标记序列),它将失败。

但编写它是一种奇怪的方式。

#ifdef SYNC测试SYNC是否已定义,而不考虑 的定义。

#elif !SYNC测试SYNC是否扩展为带有 false 值的表达式。如果根本没有定义SYNC,预处理器会将标识符SYNC扩展为0#elif !0完全合法。但是,如果将SYNC定义为扩展为!的有效操作数,则会出错。

例如,如果我使用gcc ...gcc -DSYNC ...编译上述内容(后者将SYNC定义为1),那么就没有错误,我得到了第一个或第二个代码块。

但如果我用gcc -DSYNC= ...编译它,将SYNC定义为空标记序列,那么#elif会扩展为:

#elif !

这是一个语法错误。添加括号无济于事;它只是更改错误消息。

我认为,真正的问题在于,您是否正在测试是否定义了SYNC,并测试其值是真还是假。

你很可能不需要#elif;只需#else即可。

如果要根据是否定义SYNC来选择要编译的代码块,只需写:

#ifdef SYNC
/* ... */
#else
/* ... */
#endif

如果您想测试SYNC是真还是假(并注意如果SYNC未定义为宏,则扩展为0),您可以写:

#if SYNC
/* ... */
#else
/* ... */
#endif

您可以使用任何一种形式,但我个人更喜欢#ifdef(除非SYNC的不同定义值之间存在一些有意义的区别。)

请注意,预处理器具有#ifdef#ifndef指令,但它没有#elifdef#elifndef。如果您需要在#else中测试定义,请使用defined运算符:

...
#elif defined(SYNC)
...

但在这种情况下,我认为你不需要这样做。

答案 1 :(得分:3)

最简单的是

#ifdef SYNC
defined
#else
undefined
#endif

或更接近您的代码:

#ifdef SYNC
defined
#elif !defined SYNC
undefined
#endif

答案 2 :(得分:-1)

我认为你正在寻找这个:

#ifdef SYNC
defined
#elif !(SYNC)
undefined
#endif

现在运行预处理器gcc -E test.c输出:

undefined

注意:您也可以使用#if (SYNC),效果与#ifdef相同。