"semantics violation does not require diagnostics"的理由是什么?

What is the rationale for "semantics violation does not require diagnostics"?

后续问题:

ISO/IEC 9899:202x (E) 工作草案——2020 年 12 月 11 日 N2596,5.1.1.3 诊断,1:

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.

结果:语义违规不需要诊断。

问题:“语义违规不需要诊断”的(可能)理由是什么?

Rice's theorem 给出了一个可能的基本原理:程序的重要语义属性是不可判定的

例如,除以零是违反语义的;并且您无法仅通过对 C 源代码的静态分析来决定它不会发生...

标准不能要求完全检测此类未定义的行为,即使某些工具(例如 Frama-C有时 能够检测到它们。

另见 halting problem。你不应该指望 C 编译器来解决它!

C99 rationale v5.10给出了这样的解释:

5.1.1.3 Diagnostics

By mandating some form of diagnostic message for any program containing a syntax error or constraint violation, the Standard performs two important services. First, it gives teeth to the concept of erroneous program, since a conforming implementation must distinguish such a program from a valid one. Second, it severely constrains the nature of extensions permissible to a conforming implementation.

The Standard says nothing about the nature of the diagnostic message, which could simply be “syntax error”, with no hint of where the error occurs. (An implementation must, of course, describe what translator output constitutes a diagnostic message, so that the user can recognize it as such.) The C89 Committee ultimately decided that any diagnostic activity beyond this level is an issue of quality of implementation, and that market forces would encourage more useful diagnostics. Nevertheless, the C89 Committee felt that at least some significant class of errors must be diagnosed, and the class specified should be recognizable by all translators.

发生这种情况是因为 C 语言的语法是上下文相关的,并且对于在 Chomsky 层次结构中使用上下文无关或更复杂的语法定义的所有语言,必须在语言的语义及其功能之间进行权衡。

C 语言的设计者选择赋予语言更多的权力,这就是为什么不可判定性问题在 C 语言中无处不在。

像 Coq 这样的语言试图消除不可判定的情况,并且它们限制了递归函数的语义(它们只允许 sigma(原始)递归)。

实施是否在任何特定情况下提供任何有用诊断的问题是标准管辖范围之外的实施质量问题。如果一个实现无条件地输出“警告:这个程序不输出任何有用的诊断”甚至“警告:水是湿的”,这样的输出将完全满足标准关于诊断的所有要求,即使实现没有输出任何其他诊断信息。

此外,该标准的作者将他们期望的许多操作描述为“未定义行为”,这些操作将由许多(如果不是大多数)实现以有意义和有用的方式进行处理。根据已发布的基本原理文档,未定义行为除其他事项外“标识了符合语言扩展的区域”,因为允许实现指定它们在标准未定义的情况下的行为方式。

让实现发出关于不可移植但它们会以有用的方式处理的构造的警告会很烦人。

在标准之前,一些实现会有效地接受如下结构:

struct foo {
  int *p;
  char pad [4-sizeof (int*)];
  int q,r;
};

对于最多四个字节的所有大小的指针(当时还没有 8 字节指针),而不是尖叫指针正好是四个字节,但委员会中的一些人反对这个想法接受零大小数组的声明。因此,达成了一种妥协,编译器会抱怨这些事情,程序员会忽略无用的警告,而有用的结构在支持它们的实现上仍然可用。

虽然有一个模糊的尝试来区分应该产生程序员可以忽略的警告的构造,以及可能被使用得太多以至于警告会很烦人的构造,但 的发布是有用的 诊断是标准管辖范围之外的实施质量问题,这意味着没有必要过分担心此类区别。