如何解决提供在不生成诊断消息的情况下违反“应该”要求的能力是编译器错误/缺陷或功能吗?
上下文:C 标准没有将诊断消息归类为“警告”或“错误”。
问题:通过将某些“诊断消息”视为“警告”并提供禁用警告生成的能力,某些编译器实现允许最终用户违反 C 标准的“应”要求,而无需生成警告诊断消息。这个津贴是编译器错误/缺陷吗?如果不是,那么如何正确解释这种情况?作为“允许在不生成诊断消息的情况下违反“应”要求的编译器功能?
示例:
#pragma warning( disable : 34 )
typedef int T[];
int main()
{
return sizeof(T);
}
$ cl t28.c /Za
<no diagnostic messages,the "shall" requirement [1] is silently violated>
[1] ISO/IEC 9899:1990:
sizeof 运算符不得应用于具有函数类型或不完整类型的表达式。
更新。
- 如果指定了
/Za
(禁用语言扩展),则__STDC__
的定义为定义 1。 - 根据
ANSI Conformance
页 (https://docs.microsoft.com/en-us/cpp/c-language/ansi-conformance?view=msvc-160):
Microsoft C 符合 ANSI C 标准 9899:1990 版中规定的 C 语言标准。
解决方法
C 2018 6.10.6 讨论了 #pragma
指令。第 1 段说:
... 使实现以实现定义的方式运行。该行为可能会导致翻译失败或导致翻译器或生成的程序以不符合规定的方式运行......
这在很大程度上允许实现做任何它想做的事情,只要它记录下来。如果 #pragma warning( disable : 34 )
被记录为禁用警告,这就是它所做的,那么这就是符合。
请特别注意,#pragma
“可能……导致翻译……以不符合规范的方式行事。”所以,做一些不符合规范的事情,因为一个 pragma 告诉你是符合规范的。
(我认为原文应该说 #pragma
可能会导致翻译器或程序以否则不符合的方式行事。因为,正如目前所写,在这方面的行为记录不合格的方式是合格,不是不合格。)
标准中的“应”(和“不应”)要求有两种不同的类型:对程序的限制和对实施的限制。
对实现的限制是实现必须(或不能)做的事情——这些可能有与之相关的强制性诊断。
对程序的限制实际上是实现的自由——它们是——如果程序执行它们——会导致未定义的行为,因此实现可以对他们做任何事情并且仍然符合要求。
上面的示例“sizeof 运算符不应应用于“...是对程序的限制。因此,这样做的程序不符合规范,而实现可以做任何它想做的事情(包括将其视为不需要标志或编译指示的扩展)并且仍然符合规范。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。