如果在翻译单元中定义了标签,则通过ifdef以编程方式确定

时间:2012-04-02 01:12:01

标签: c++ label conditional-compilation

我有以下代码,我希望包含cstdio,第一行将被打印,但第二行打印。

我做错了什么?是否可以知道在编译时是否在当前翻译单元中定义了printf或strncmp或memcpy等标签?

#include <iostream>
#include <cstdio>

int main()
{
   #ifdef printf
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

原因是因为在将变量和标签引入范围/ TU之前运行预处理器吗?

总之是以下代码伪造? :

http://code.google.com/p/cmockery/source/browse/trunk/src/example/calculator.c#35

3 个答案:

答案 0 :(得分:6)

#ifdef仅适用于使用#define定义的预处理器宏,而不适用于函数名称和变量等符号。您可以将预处理器想象为一个实际的单独预备步骤,例如通过perl脚本运行代码,这是在“真正的”编译器得到破解之前发生的。

因此,没有编程方法来检查当前作用域中是否定义了printf之类的符号。如果您使用一个并且未定义,则会出现编译器错误。正常的做法是#include在您引用它的源文件中具有所需定义的头文件,而不是编写将自己适应不同可能的头集的源文件。

作为一个hack,并且根据您的环境和特定问题,定义printf(或您关心的任何函数)的头文件也可能包含一些您可以检查的预处理器#define

答案 1 :(得分:3)

您可以使用原始包含文件中的警卫来确定它们是否包含在内,从而声明了函数。

例如,我的MSVS2010附带的<stdio.h>_INC_STDIO名警卫。因此,您的代码应该是:

int main()
{
   #ifdef _INC_STDIO
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

请注意,此解决方案依赖于环境,因此您应该创建更复杂的规则,以便支持多个构建链。

答案 2 :(得分:2)

它们是stdio.h中的大量符号#define d,它是由cstdio导入的

所以你可以使用

#include <iostream>
#include <cstdio>

int main()
{
   #ifdef stdin
      std::cout << "printf is defined.\n";
   #else
      std::cout << "printf NOT defined!\n";
   #endif
   return 0;
}

警告我看过标题但未经过测试。