通过ifdef以编程方式确定是否在翻译单元中定义了标签

Programmatically determine via ifdef if a label is defined within a Translation Unit

本文关键字:单元 翻译 定义 标签 是否 ifdef 编程 方式确 通过      更新时间:2023-10-16

我有下面的代码,我希望给定的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中的大量符号,它们是#defined,由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;
}

警告我看过标题,但没有测试。