_Pragma和宏替换
在实现我自己的C11编译器时,我试图找出如何处理_Pragma关键字/运算符. C11§6.10.9将_Pragma描述为一个运算符,所以似乎有可能用宏重新定义它,即#define _Pragma(x)SOME_OTHER_MACRO(x).此外,#undef _Pragma的声明应该没有任何效果(假设没有_Pragma的先前的#define).这类似于关键字如何#defined,如旧的VC hack #define for if(0);其他的.但是,由于_Pragma运算符在转换阶段3期间被执行,与执行预处理器指令相同,所以不清楚这是否是异常;该标准没有提到它的未定义行为是否使用_Pragma作为宏名称.
我用GCC做了一些测试,使用下面的代码: #define PRAGMA _Pragma PRAGMA("message "hi"") _Pragma ("message "sup"") #undef PRAGMA #undef _Pragma //#define _Pragma(x) _Pragma("message "hello"") 编译gcc -std = c11 -pedantic -Wall -Wextra -c输出: tmp.c:2:1: note: #pragma message: hi PRAGMA("message "hi"") ^ tmp.c:4:1: note: #pragma message: sup _Pragma ("message "sup"") ^ tmp.c:8:8: warning: undefining "_Pragma" [enabled by default] #undef _Pragma ^ tmp.c:10:9: error: expected declaration specifiers or ‘...’ before string constant _Pragma("message "hello"") ^ 如果我添加#undef _Alignof行,GCC不会抱怨. 这表明GCC通过宏(通过警告消息)来实现_Pragma,并且不定义它会导致编译错误.如果我取消注释#define _Pragma(x),则该错误消失(因为字符串文字消失). 所以我的问题是: >实现允许将_Pragma定义为一个宏,而不是将其作为运算符实现? 再次,通过C11标准,除了可以用于#pragma指令的操作符之外,并没有提到关于_Pragma的任何内容. 解决方法
不需要一个禁止_Pragma成为宏名称的特殊规则.有一个领先的下划线和大写字母,它是保留的标识符,你不应该使用,无论如何.使用保留的标识符导致程序的未定义的行为,编译器可能会做任何事情.
一个实现可以将其实现为一个宏,但这应该对你来说是透明的,只要你正确使用它,只要你不会弄乱它.实现必须保证的唯一重要的事情是,在_Pragma的参数的“destringization”和“tokeninzation”就像在阶段3中一样完成(如果它只是“只”一个宏),那么这个结果# pragma指令在第4阶段进行处理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |