我有以下代码,我希望包含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
答案 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;
}
警告我看过标题但未经过测试。