我试着写一个宏,像这样:摘自链接我把同样的规则应用到我的软件上,但没有成功。我注意到C和c++的一些差异,但我不明白为什么,宏是预处理器的工作!我还注意到将来自枚举数的值传递给宏有一些不同。
#include <stdio.h>
#define CONCAT(string) "start"string"end"
int main(void)
{
printf(CONCAT("-hello-"));
return 0;
}
报告的链接用于在线尝试代码链接到ideone上的演示允许选择不同的语言C还可以,但换成c++就不行了。也在我的IDE Visual Studio Code (MinGw c++)不工作。
我的最终目标是写一个宏来参数化printf()函数,用于虚拟控制台应用程序,使用一些转义码。我尝试将#添加到宏连接中,并且似乎有效,但如果我将枚举器传递给宏,则会产生意想不到的结果。代码是:
#include <stdio.h>
#define def_BLACK_TXT 30
#define def_Light_green_bck 102
#define CSI "e["
#define concat_csi(a, b) CSI #a ";" #b "m"
#define setTextAndBackgColor(tc, bc) printf(concat_csi(bc, tc))
enum VtColors { RESET_COLOR = 0, BLACK_TXT = 30, Light_green_bck = 102 };
int main(void){
setTextAndBackgColor(30, 102);
printf("rn");
setTextAndBackgColor(def_BLACK_TXT , def_Light_green_bck );
printf("rn");
setTextAndBackgColor(VtColors::BLACK_TXT , VtColors::Light_green_bck );
printf("rn");
printf("e[102;30m");// <<--- this is the expected result of macro expansion
}
//and the output is : ( in the line 3 seems preprocessor don't resolve enum (the others line are ok) )
[102;30m
[102;30m
[VtColors::Light_green_bck;VtColors::BLACK_TXTm
[102;30m
显然我想使用枚举数作为参数…(或者改成#define).
但是我很想知道为什么会发生这种情况,为什么C和c++的预处理器会有不同。
如果有人知道解决方法,非常感谢。
这里似乎有一些编译器的分歧。
MSVC将其编译为c++,没有任何问题。
gcc产生编译错误。
编译错误引用了一个名为"用户定义的文字"的c++特性,其中语法"something"suffix
被解析为用户定义的文字(假设这个用户定义的文字得到了正确的声明)。
由于预处理器阶段应该发生在编译阶段之前,因此我得出结论,编译错误是编译器错误。
请注意,添加一些空格会产生相同的结果,无论它被编译为C或c++(并使gcc高兴):
#define CONCAT(string) "start" string "end"
编辑:从c++ 11开始,用户定义的字面值被认为是不同的令牌:
第三阶段
- 源文件被分解为注释、序列和注释空白字符(空格、水平制表符、换行、垂直制表符、和表单提要),以及预处理令牌,它们如下:
)头文件名称,如或"myfile.h">
b)标识符
c)预处理数字d)字符和字符串字面量,包括用户定义的(c++ 11起)
我特别强调。
这发生在阶段4:预处理器执行之前,所以这里的编译错误是正确的结果。"start"string
没有中间的空格,在预处理器阶段之前被解析为用户定义的文字。
行为总结如下:(见代码中的注释)
#include <stdio.h>
#define CONCAT_1(string) "start"#string"end"
#define CONCAT_2(string) "start"string"end"
#define CONCAT_3(string) "start" string "end"
int main(void)
{
printf(CONCAT_1("-hello-")); // wrong insert double quote
printf("rn");
printf(CONCAT_1(-hello-)); // OK but is without quote
printf("rn");
#if false
printf(CONCAT_2("-hello-")); // compiler error
printf("rn");
#endif
printf(CONCAT_3("-hello-")); // OK
printf("rn");
printf("start" "-hello-" "end"); // OK
printf("rn");
printf("start""-hello-""end"); // OK
printf("rn");
return 0;
}
output:
start"-hello-"end <<<--- wrong insert double quote
start-hello-end
start-hello-end
start-hello-end
start-hello-end