C++与C宏字符串串联的差异

pgvzfuti  于 2023-01-10  发布在  其他
关注(0)|答案(2)|浏览(302)

我试着写一个宏如下:从link和我应用相同的规则到我的软件whit out成功。我注意到一些不同的C和C++,但我不明白为什么,宏是预处理器的工作!我也注意到一些不同的传递到宏的值来自枚举器。

#include <stdio.h>
#define CONCAT(string) "start"string"end"
int main(void) 
{
    printf(CONCAT("-hello-"));
    return 0;
}

报告的链接用于尝试在线代码link to a demo on ideone允许选择不同的语言C是可以的,但更改为C它不工作。此外,在我的IDE Visual Studio代码(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("\r\n");
    setTextAndBackgColor(def_BLACK_TXT , def_Light_green_bck );
    printf("\r\n");
    setTextAndBackgColor(VtColors::BLACK_TXT , VtColors::Light_green_bck );
    printf("\r\n");
    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++的预处理器会有不同。
如果有人知道解决办法,非常感谢。

guz6ccqo

guz6ccqo1#

这里似乎有一些编译器的分歧。
MSVC将其编译为as C++ without any issues
海湾合作委员会
编译错误引用了一个名为"user-defined literals"的C特性,其中语法"something"suffix被解析为用户定义的文本(假设此用户定义的文本被正确声明)。
由于预处理阶段应该在编译阶段之前发生,因此我认为编译错误是一个编译器bug。
注意,添加一些空格会产生相同的结果,无论它被编译成C还是C
(并且使gcc满意):

#define CONCAT(string) "start" string "end"

EDIT:自C11起,用户定义的文字are considered to be distinct tokens
第三阶段
1.源文件被分解为注解、空白字符序列(空格、水平制表符、换行符、垂直制表符和换页符)和预处理标记,如下所示:
a)标头名称,例如或"myfile. h"
b)识别码
c)预处理数字d)字符和字符串字面量,**包括用户定义(C
11起)**
我强调。
这发生在第4阶段之前:预处理器执行,所以这里的编译错误是正确的结果。"start"string(中间没有空格)在预处理器阶段之前被解析为用户定义的文本。

kb5ga3dv

kb5ga3dv2#

行为总结如下:(参见代码中的注解)

#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("\r\n");
    printf(CONCAT_1(-hello-));        // OK but is without quote
    printf("\r\n");
#if false
    printf(CONCAT_2("-hello-"));   // compiler error
    printf("\r\n");
#endif
    printf(CONCAT_3("-hello-"));     // OK
    printf("\r\n");
    printf("start" "-hello-" "end");    // OK
    printf("\r\n");
    printf("start""-hello-""end");      // OK
    printf("\r\n");
    return 0;
}
output:
start"-hello-"end   <<<--- wrong insert double quote
start-hello-end
start-hello-end
start-hello-end
start-hello-end

相关问题