包含由 C/C++ 宏连接生成的字符串 [重复]

Posted

技术标签:

【中文标题】包含由 C/C++ 宏连接生成的字符串 [重复]【英文标题】:Include string generated by C/C++ macro concatenation [duplicate] 【发布时间】:2020-11-13 21:34:51 【问题描述】:

我正在尝试包含一个名称取决于版本的头文件。具体名称 由字符串与版本号的串联给出。最后一个被找回 从 CMakeLists.txt 使用配置文件。

#include "config.h" # load PROJECT_VER
#define HEADERROOT "foo-"
#define HEADERBASENAME HEADERROOT PROJECT_VER
#define HEADER HEADERBASENAME ".h"
// Equivalent to: #define HEADER "foo-5.1.h"

生成的字符串是正确的,但是不能包含它(附加到前面的语句)

#include HEADER
#include <iostream>
using namespace std;

int main() 
    
    cout << HEADER << endl;
    return 0;

错误是

main.cpp:6:10: warning: extra tokens at end of #include directive
 #include HEADER
          ^~~~~~
main.cpp:6:16: fatal error: foo-: No such file or directory
 #include HEADER
                ^
compilation terminated.

【问题讨论】:

是的,因为#include 中的东西不是字符串 你要么想办法绕过不同的名称,要么用 bash 脚本或其他东西生成名称。 您必须从一开始就将整个文件名存储在一个宏中。 您的方法的一个问题是预处理器是编译的第 4 阶段,而相邻字符串文字的连接是第 6 阶段。因此,为此目的,#define HEADER "foo-" "5.1" ".h" 不是 相当于#define HEADER "foo-5.1.h"(嗯...我假设您隐含的问题是如何实现您的目标,而不是您的方法为何失败?如果该假设是错误的,我可以将此评论转换为答案。) 我解决了它在config.h.in 中添加另一个#define 和全名。 【参考方案1】:

您不能使用宏来定义#include 语句的文件名。这种任务最好在外部构建过程中处理,该过程在调用预处理器/编译器之前创建必要的源代码。

【讨论】:

您可以写#include HEADER,只要宏名称扩展为”header.h”&lt;header.h&gt;。问题的问题是宏扩展为多个字符串,字符串连接只有在预处理完成后才会发生。

以上是关于包含由 C/C++ 宏连接生成的字符串 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C/C++ 宏字符串连接

请问如何把lib(C语言编的)同其带有宏定义的.h文件封装起来 生成一个新的文件供C#调用?

1. 宏定义

写好 C/C++,漂亮的宏定义很重要!

写好 C/C++,漂亮的宏定义很重要!

C++ "#"的作用和用法