c++与C宏字符串连接的差异



我试着写一个宏,像这样:摘自链接我把同样的规则应用到我的软件上,但没有成功。我注意到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开始,用户定义的字面值被认为是不同的令牌:

第三阶段

  1. 源文件被分解为注释、序列和注释空白字符(空格、水平制表符、换行、垂直制表符、和表单提要),以及预处理令牌,它们如下:

)头文件名称,如或"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

相关内容

  • 没有找到相关文章

最新更新