加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

_Pragma和宏替换

发布时间:2020-12-16 03:09:26 所属栏目:百科 来源:网络整理
导读:在实现我自己的C11编译器时,我试图找出如何处理_Pragma关键字/运算符. C11§6.10.9将_Pragma描述为一个运算符,所以似乎有可能用宏重新定义它,即#define _Pragma(x)SOME_OTHER_MACRO(x).此外,#undef _Pragma的声明应该没有任何效果(假设没有_Pragma的先前的#d
在实现我自己的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定义为一个宏,而不是将其作为运算符实现?
>如果不是,GCC错了吗?
>如果_Pragma应该是一个运算符,是否定义_Pragma作为宏的未定义的行为?
> _Pragma评估和其他预处理指令之间是否有任何排序?或者他们是否具有相同的“优先级”(即按顺序评估)?

再次,通过C11标准,除了可以用于#pragma指令的操作符之外,并没有提到关于_Pragma的任何内容.

解决方法

不需要一个禁止_Pragma成为宏名称的特殊规则.有一个领先的下划线和大写字母,它是保留的标识符,你不应该使用,无论如何.使用保留的标识符导致程序的未定义的行为,编译器可能会做任何事情.

一个实现可以将其实现为一个宏,但这应该对你来说是透明的,只要你正确使用它,只要你不会弄乱它.实现必须保证的唯一重要的事情是,在_Pragma的参数的“destringization”和“tokeninzation”就像在阶段3中一样完成(如果它只是“只”一个宏),那么这个结果# pragma指令在第4阶段进行处理.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读