通过ifdef以编程方式确定是否在翻译单元中定义了标签
Programmatically determine via ifdef if a label is defined within a Translation Unit
我有下面的代码,我希望给定的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
#ifdef
仅适用于用#define
定义的预处理器宏,而不适用于函数名和变量等符号。您可以将预处理器想象成一个实际的独立的初步步骤,就像通过perl脚本运行代码一样,它发生在"真正的"编译器破解它之前
因此,没有程序化的方法来检查像printf
这样的符号是否在当前范围中定义。如果你使用了一个,但它没有定义,你会得到一个编译器错误。通常要做的事情是在引用它的源文件中#include
一个具有所需定义的头文件,而不是编写一个将自己适应不同可能的头集的源文件。
作为一种破解,根据您的环境和特定问题,定义printf
(或您关心的任何函数)的头文件也可能包含一些您可以检查的预处理器#define
。
您可以使用原始包含文件中的保护来确定它们是否被包含,从而确定函数是否被声明。
例如,我的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;
}
请注意,此解决方案依赖于环境,因此您应该创建更复杂的规则——您应该支持多个构建链。
它们是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;
}
警告我看过标题,但没有测试。
- 不同翻译单元中不可重载的非内联函数定义
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 如何执行 cppcheck 交叉翻译单元 (CTU) 静态分析?
- 模板变量是否允许在多个翻译单元中并有效合并?
- 是否允许类在程序中的不同翻译单元之间具有不同的定义?
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 为什么不同的翻译单元没有独立和沙盒的内存空间?
- 为什么编译器不在同一翻译单元中警告 ODR 违规
- 静态变量在同一个翻译单元中被静态方法使用时是否保证被初始化?
- 来自不同翻译单元的函数会干扰吗?
- 如何在C++中的不同翻译单元之间共享枚举的实例
- 在C++中声明"interface",而不是将其 vtable 发送到每个翻译单元
- MSVC 2017 在单个翻译单元中违反静态初始化顺序
- 在不同的翻译单元中启动全局变量(涉及链接)
- 链接器如何处理跨翻译单元的相同模板实例化
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 翻译单元的数量与CPP文件的数量
- GCC 6.3.0 中的 ODR 冲突,类型在两个单独的翻译单元中定义
- 为什么结构和类定义可以在多个翻译单元上重复?
- 如果在同一翻译单元中调用功能,为什么需要搬迁