C 预处理器:包含基于定义

Posted

技术标签:

【中文标题】C 预处理器:包含基于定义【英文标题】:C preprocessor: include based on define 【发布时间】:2014-10-04 23:06:36 【问题描述】:

如何根据已定义字符串的值包含文件或其他文件?

这不起作用:

#define VAR VALUE_A

#if VAR == "VALUE_A"
    #include "a.h"
#elif VAR == "VALUE_B"
    #include "b.h"
#endif

如果它很重要,我实际上并没有定义VAR,而是通过gcc -D NAME=VALUE 从命令行传递它。

【问题讨论】:

【参考方案1】:

== 运算符不比较字符串。但是您还有其他几个选项来配置您的包含。除了其他答案中已经提到的解决方案之外,我喜欢这个,因为我认为它是不言自明的。

/* Constant identifying the "alpha" library. */
#define LIBRARY_ALPHA 1

/* Constant identifying the "beta" library. */
#define LIBRARY_BETA 2

/* Provide a default library if the user does not select one. */
#ifndef LIBRARY_TO_USE
#define LIBRARY_TO_USE LIBRARY_ALPHA
#endif

/* Include the selected library while handling errors properly. */
#if LIBRARY_TO_USE == LIBRARY_ALPHA
#include <alpha.h>
#elif LIBRARY_TO_USE == LIBRARY_BETA
#define BETA_USE_OPEN_MP 0  /* You can do more stuff than simply include a header if needed. */
#include <beta.h>
#else
#error "Invalid choice for LIBRARY_TO_USE (select LIBRARY_ALPHA or LIBRARY_BETA)"
#endif

您的用户现在可以编译:

$ cc -DLIBRARY_TO_USE=LIBRARY_BETA whatever.c

【讨论】:

【参考方案2】:

您可以使用#ifdef#ifndef 进行条件包含。

#ifdef VALUE_A
  #include "a.h"
#endif

#ifdef VALUE_B
  #include "b.h"
#endif

【讨论】:

【参考方案3】:

我能想到的最接近的可能性是利用#include 指令的第三种形式(C11 §6.10.2/4),即用值定义VAR,它包含实际的头文件名:

#define VAR "a.h"

然后只需使用以下内容:

#include VAR

【讨论】:

+1 为什么投反对票?如果@GrzegorzSzpetkowski 不会更快,我也会自己提出这个建议。这是一种非常灵活的技术,对于在库中提供挂钩特别有用。

以上是关于C 预处理器:包含基于定义的主要内容,如果未能解决你的问题,请参考以下文章

C 基础 - 预处理器与C库

基于 NuGet PackageReference 定义一个 C# 预处理器符号

来自 C++ 代码的预处理器指令 (_VARIADIC_MAX)

Visual C ++转储预处理器定义

预处理器中的 C# 宏定义

C语言基础:C 预处理器预定义宏预处理器运算符(字符串常量化运算符(#),标记粘贴运算符(##),defined 运算符)参数化的宏