预处理器指令#include 可以禁用/排除吗?

Posted

技术标签:

【中文标题】预处理器指令#include 可以禁用/排除吗?【英文标题】:Can preprocessor directive #include be disabled/excluded? 【发布时间】:2011-11-29 10:29:33 【问题描述】:

例如:如果我有两个 .h 文件

process1.h 和 process2.h

它们包含两个具有不同输出变量的函数。

process1.h:

function(int var)
 
 return 2*var;

process2.h:

function(int var)
 
 return 10*var;

这可以在main.c中完成吗:

int main()

int a = 2;
#include "process1.h"
printf("%d",function(a));    //output is 4

EXCLUDE #INCLUDE "process1.h" ?????    <----can this be done in any way??
#include "process2.h"
printf("%d",function(a));    //output is 20


【问题讨论】:

【参考方案1】:

不,您不能“取消包含”文件。将所有预处理器指令(以# 开头的行)想象为发生在实际C 编译器甚至看到源文件之前。它们只是对文件的文本进行操作,而预处理器可以作为一个单独的步骤来实现,它只是将新文本输入到实际的编译器中。

根据调用者修改include 的操作的最佳方法是在包含的文件中使用更多宏,您可以在包含它们之前#define

不过,你的整体语法是关闭的,你不能(通常)在 C 中嵌套函数。

【讨论】:

【参考方案2】:

不,您不应该尝试编写具有两个同名函数的程序。

在函数实际定义在头文件中(而不仅仅是原型)的特殊情况下,您可以这样做:

#define function function_file1
#include "file1.h"
#undef function

#define function function_file2
#include "file2.h"
#undef function

int
main (void)
  
    int a = 2;

    printf ("%d\n", function_file1 (a));
    printf ("%d\n", function_file2 (a));
  

但是如果你重命名一个函数原型,那么你实际上并没有重命名真正的函数,所以当你链接时你会得到未定义的符号错误。

无论如何,如果您定义了两个具有相同名称的函数,那么无论如何它都不会链接,无论您在源代码中还做了什么。 (在 C++ 中,有时可以定义两个具有相同名称的事物,但 One-Definition-Rule 意味着允许链接器假定它们实际上是相同的事物并且只选择一个。)

这就是为什么图书馆应该使用不会在其他地方使用的名称 - 通常是通过为所有符号名称添加一个公共前缀(例如my_unique_lib_initialize())。

【讨论】:

【参考方案3】:

为什么不使用函数指针数组。当然,您需要在开始时对其进行初始化,但我认为它可能会解决您想要做的事情。

int process1_function(int var);
int process2_function(int var);

int main(void)

    int i, a = 10;
    int (* functions[2])(int);

    functions[0] = process1_function;
    functions[1] = process2_function;

    for(i=0; i < 2; i++)
    
        printf("%d", (functions[i])(a));
    

    return 0;

如果您不需要动态更改要调用的函数,您也可以只为函数添加前缀:

int process1_function(int var);
int process2_function(int var);

int main(void)

   printf("%d",process1_function(a));
   printf("%d",process2_function(a));

   return 0;

【讨论】:

以上是关于预处理器指令#include 可以禁用/排除吗?的主要内容,如果未能解决你的问题,请参考以下文章

#define 预处理器指令可以包含 if 和 else 吗?

预处理器的相关知识:

什么时候可以在#include指令中省略文件扩展名?

您可以为 C# 版本添加预处理器指令吗?

你可以嵌套 C 预处理器指令吗?

2020年01月30日