【问题标题】:Include string generated by C/C++ macro concatenation [duplicate]包含由 C/C++ 宏连接生成的字符串 [重复]
【发布时间】: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 和全名。

标签: c++ c cmake include c-preprocessor


【解决方案1】:

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

【讨论】:

  • 您可以写#include HEADER,只要宏名称扩展为”header.h”&lt;header.h&gt;。问题的问题是宏扩展为多个字符串,字符串连接只有在预处理完成后才会发生。
猜你喜欢
  • 2011-07-12
  • 1970-01-01
  • 2012-07-16
  • 2017-08-27
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多