【问题标题】:C pre-processor errorC 预处理器错误
【发布时间】:2014-07-09 13:40:07
【问题描述】:

我希望代码输出 suse.sys,但它实际上打印了 win.sys。为什么会这样?

 #define SYS SUSE

 #if SYS == WIN
   #define HDR "win.sys"
 #elif SYS == SUSE
   #define HDR "suse.sys"
 #else
   #define HDR "default.sys"
 #endif
 #include HDR
 #include <stdio.h>

 int main()
 {
   char *name = HDR;
   printf("%s\n", name);
   return 0;
 }

这类似于 C 编程语言第二版中的示例。 .sys 文件不包含任何内容,它们没有实际用途。

【问题讨论】:

  • 是否定义了HDRSUSE
  • 第一个#if被替换为#if SUSE == WINSUSEWIN(我假设)没有定义,所以它们默认为0(因为它们在算术表达式中使用) ,所以它被评估为#if 0 == 0,也就是1,所以HDR被定义为"suse.sys"。您似乎想通过预处理器比较字符串,这是不可能的。
  • @CSSStudent,正如 mafso 指出的那样:无法比较字符串
  • 所以你可以再添加两个定义:#define WIN 0#define SUSE 1 或类似的东西

标签: c include c-preprocessor kernighan-and-ritchie


【解决方案1】:

== 的预处理器比较适用于整数值,而不是字符串或宏名称。您应该能够通过首先使用整数值定义宏 SUSEWIN 来解决此问题,例如,

#define SUSE 1
#define WIN 2
#define SYS SUSE

在此之后,SYSSUSE 都解析为整数 1,并且应该可以进行比较。

但是,我建议采用更传统的方法为系统完全定义不同的宏,例如:

#define SYS_SUSE
//#define SYS_WIN

#if defined(SYS_SUSE)
#define HDR "suse.sys"
#elif defined(SYS_WIN)
#define HDR "win.sys"
#else
#define HDR "default.sys"
#endif

这种方法的优点是能够更方便地在命令行、makefile 等上指定系统,而无需依赖在每个上下文中定义的数字常量:

cc -DSYS_WIN -c foo.c

【讨论】:

  • +1 同时提供,一个接近 OP 如何尝试的解决方案和一个更好的方法来做同样的事情(包括推理为什么它更好)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
相关资源
最近更新 更多