提问人:anol 提问时间:6/9/2023 更新时间:6/9/2023 访问量:49
在函数原型声明的中间是否允许_Pragma运算符?
Are _Pragma operators allowed in the middle of function prototype declarations?
问:
我遇到过一些这样的代码:
void _Pragma("function") f() {
int i = 0;
_Pragma("loop");
while (i < 100) {
...
}
}
GCC 编译它没有问题。但是我看不出它允许 出现在这些位置的标准中的确切位置,尤其是在 和 之间。_Pragma
void
f()
我的 C11 标准 (N1570) 版本规定:
6.10.9 编译指示运算符
语义学
形式的一元运算符表达式:
_Pragma ( string-literal )
...
给出的示例的行为几乎为 ,这意味着,在一条线上。#pragma
第 6.5.3 节。一元运算符甚至没有提到._Pragma
我在句法规则中没有看到一元运算符被允许位于 和 之间的位置。void
f()
GCC 文档只是声称:
该标准尚不清楚操作员可以出现在哪里。
_Pragma
我认为在语法上没有明确允许的任何地方都是被禁止的。
是未指定或实现定义的,以允许出现此类情况?_Pragma
答:
_Pragma
几乎只有一个目的:允许您在预处理器宏中使用编译指示。将其用于任何其他目的没有(不应该)有意义。#define
除此之外,6.10.9 说:
生成的字符序列通过转换阶段 3 进行处理,以生成预处理标记,这些标记就像 pragma 指令中的 pp 标记一样执行。
你可以把它解释为:本来是要写在自己的一行上,因为作为一个预处理器指令,它就是这样工作的。在这种情况下,由于诸如 之类的代码是无效的,因此 也应该如此。#pragma
void #pragma function
_Pragma
引用您找到的 gcc 文档:
为了安全起见,您可能最好将其排除在 #define 以外的指令之外,并将其放在自己的行上。
此外,一般的最佳实践包括:
- 不要仅仅为了它而编写奇怪的代码。
- 不要仅仅为了它而使用奇怪的编译器扩展。
尽管编译器应该忽略无法识别的编译指示,这似乎是 gcc、clang 等人正在做的事情。如果您使用严格的设置进行编译,则两者都不会“毫无问题地编译它”,它们会发出警告,然后忽略它。-std=c17 -pedantic -Wall -Wextra
评论
"Hello " _Pragma("") " world!\n"
#
##
defined
_Pragma
_Pragma