【发布时间】:2013-05-20 18:28:34
【问题描述】:
我正在读一本书来学习 C。在那本书中,下面的示例代码给出了 gcc (Debian 4.7.2-4) 4.7.2 的预处理器错误。错误是:
file.c:在函数“main”中:
file.c:16:14: 错误:令牌“我知道 C 语言。\n”在预处理器表达式中无效
file.c:20:14: error: token ""I know BASIC.\n"" 在预处理器表达式中无效
代码是:
#include <stdio.h>
#define C_LANG 'C'
#define B_LANG 'B'
#define NO_ERROR 0
int main(void)
{
#if C_LANG == 'C' && B_LANG == 'B'
#undef C_LANG
#define C_LANG "I know the C language.\n"
#undef B_LANG
#define B_LANG "I know BASIC.\n"
printf("%s%s", C_LANG, B_LANG);
#elif C_LANG == 'C'
#undef C_LANG
#define C_LANG "I only know C language.\n"
printf("%s", C_LANG);
#elif B_LANG == 'B'
#undef B_LANG
#define B_LANG "I only know BASIC.\n"
printf("%s", B_LANG);
#else
printf("I don't know C or BASIC.\n");
#endif
return NO_ERROR;
}
是 gcc 预处理器无法正确执行此操作,还是代码有问题需要更改?
【问题讨论】:
-
我认为是 printfs 搞砸了。
-
不,是#elif 行有问题。例如,预处理器将第一个#elif 扩展为
#elif "I know the C language.\n" == 'C',然后失败了。 ideone fails it too. -
到目前为止给出的任何一个答案都可以。但是,我必须说,如果这是书中的一个例子,您可能需要重新考虑您使用的是哪本书。
-
@cebarth:我认为你是对的。这本书是 Sam 在 24 小时内自学 C。这对于 bash 脚本编写来说非常棒,并且在几年前让我在我的道路上做得很好。当 Apress 的书 C:从新手到专业让我难以理解时,这确实帮助我掌握了指针,但它使用的是带有未知编译器的 Windows。也许预处理器“更聪明”,这让我为 gcc 感到难过。这是第 23 章,因此还有 1 章。我会完成它,但肯定会阅读其他书籍。
-
@narnie I-am-not-a-C-guru 但我建议这样的预处理器代码并不常见/不可取。我认为
gcc似乎在评估elif中的条件表达式很奇怪,即使之前的if已被检查为非零,但我可能会建议这种边缘情况并不重要.我想如果你想要这样的代码,你至少会想要使用两个不同的宏定义,就像 BLUEPIXY 建议的那样。另外,我认为如果这本书一开始就明确说明它使用的是不同的编译器,那你不能真的因此而责备它。
标签: c gcc c-preprocessor