【发布时间】:2021-07-12 04:31:31
【问题描述】:
简单问题:导致非标准行为的#pragma 是否会导致__STDC__ 宏未定义为1? (C 标准是否明确规定了这一点?如果是,那么在哪个部分?如果不是,那为什么?) 问题原因:见下文。
示例代码(t28.c):
#pragma warning( disable : 34 )
typedef int T[];
int main()
{
int rc = sizeof(T);
#if __STDC__ == 1
rc = 0;
#else
rc = 1;
#endif
return rc;
}
调用:cl t28.c /std:c11 /Za && t28 ; echo $?
预期结果:1
实际结果:0
编译器版本:
cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64
注意:C11(6.5.3.4 sizeof 和 _Alignof 运算符)(已添加重点):
sizeof 运算符不应应用于具有函数类型或不完整类型的表达式,...
这里我们看到#pragma 导致非标准行为:违反了“shall 要求”,未生成诊断消息,调用编译器的后端,生成并成功执行了.exe。但是,这种非标准行为不会导致 __STDC__ 宏未定义为 1。
问题的原因:测试。一项类似于t28.c 的测试失败,因为它需要返回码1(__STDC__ 未定义为1)。系统的哪个部分包含错误:测试或编译器(或两者)?
【问题讨论】:
-
(a)
#pragma后面没有STDC导致实现以实现定义的方式运行。这可能包括更改__STDC__的行为,但在这种情况下可能不会。但进一步回答需要说明此编译指示的实施文档。 (b) 在这个 C 实现中,__STDC__通常用什么替换(即没有#pragma并且没有代码导致编译警告或错误)? -
@thebusybee:这与
__STDC__的问题有什么关系? -
为什么你的问题会问到
__STDC__没有被定义为 1 而结果表明它是 1?你的帖子说程序的实际结果是0,这意味着#if的“then”部分被使用了,这意味着__STDC__ == 1是真的。 -
“一致的实现”是实现的属性,而不是您的代码。杂注或其他任何内容的存在不会改变实现的一致性。
-
@pmor:编译指示和命令行开关是不同的东西。为了评估一致性,每个单独的开关组合与编译器都被认为是不同的 C 实现。正在编译的源代码中存在编译指示不会使编译器成为不同的 C 实现。
标签: c visual-c++ language-lawyer c11 standards-compliance