我试着写一个宏如下:从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++的预处理器会有不同。
如果有人知道解决办法,非常感谢。
2条答案
按热度按时间guz6ccqo1#
这里似乎有一些编译器的分歧。
MSVC将其编译为as C++ without any issues。
海湾合作委员会
编译错误引用了一个名为"user-defined literals"的C特性,其中语法
"something"suffix
被解析为用户定义的文本(假设此用户定义的文本被正确声明)。由于预处理阶段应该在编译阶段之前发生,因此我认为编译错误是一个编译器bug。
注意,添加一些空格会产生相同的结果,无论它被编译成C还是C(并且使gcc满意):
EDIT:自C11起,用户定义的文字are considered to be distinct tokens:
第三阶段
1.源文件被分解为注解、空白字符序列(空格、水平制表符、换行符、垂直制表符和换页符)和预处理标记,如下所示:
a)标头名称,例如或"myfile. h"
b)识别码
c)预处理数字d)字符和字符串字面量,**包括用户定义(C11起)**
我强调。
这发生在第4阶段之前:预处理器执行,所以这里的编译错误是正确的结果。
"start"string
(中间没有空格)在预处理器阶段之前被解析为用户定义的文本。kb5ga3dv2#
行为总结如下:(参见代码中的注解)