【发布时间】:2020-11-22 05:56:10
【问题描述】:
编译下面的test.cpp
# define TopLevelProject X11
#define Concat3(a,b,c) a/**/b/**/c
# define ProjectRulesFile Concat3(<,TopLevelProject,.rules>)
#include ProjectRulesFile
cpp -I。 test.cpp
预期的行为是生成包含语句
# 1 "test.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.cpp"
# 10 "test.cpp"
# 1 "./X11.rules" 1
# 11 "test.cpp" 2
# 1 "./X11.rules" 1
# 15 "test.cpp" 2
注意这一行 "./X11.rules" 确实是输出
但是,苹果的clang cpp给出了输出
# 1 "test.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 361 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "test.cpp" 2
test.cpp:7:10: fatal error: ' X11 .rules' file not found
#include ProjectRulesFile
^~~~~~~~~~~~~~~~
test.cpp:5:35: note: expanded from macro 'ProjectRulesFile'
# define ProjectRulesFile Concat3(<,TopLevelProject,.rules>)
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:3:24: note: expanded from macro 'Concat3'
#define Concat3(a,b,c) a/**/b/**/c
^~~~~~~~~~~
1 error generated.
注意格式错误的文件名'X11 .rules'
Apple 的 cpp 在第一个参数之前插入一个空格,在 Concat3 宏的第二个和第三个参数之间插入一个空格。
所有版本的 gcc、clang 和 msdev 工具都执行正确的文本替换。
但是
所有苹果的cpp版本,比如xcode分发的,都有这个bug。
我可以使用某种宏参数连接方案来编写 Concat3 宏,以便它在苹果的 cpp 下工作吗?
谢谢
【问题讨论】:
-
# define ProjectRulesFile <TopLevelProject.rules>替换TopLevelProject并根据需要包含文件。你需要用Concat3处理<或.rules>吗?为什么? -
a/**/b/**/c不会像您认为的那样做。相当于a b c。我很惊讶它完全适用于 GCC 和香草 Clang。 -
@eric-postpischil 这是一个取自更大代码库(imake 配置文件集)的小示例,并且 Concat3 宏被多次调用,其中许多使用与我发布的相同语法。
-
@HolyBlackCat 我向你保证,最新的 plain-clang 仍然支持这一点。最新的apple-clang 的cpp,与plain-clang 版本号相同,不起作用。有没有办法通过其他策略获得相同的效果?
-
Concat3(a,b,c) a/**/b/**/c是一种古老的、预先标准的、长期弃用的连接东西的方法。它不适用于任何现代产品。
标签: c++ c clang apple-developer