c - 运行从代码生成的二进制文件是否具有 "constraint violation"实际上未定义的行为?

标签 c language-lawyer

引用:This question

上下文:main() 末尾的return 语句,没有表达式,如

 return;

当我阅读标准时,它似乎是 undefined behavior所以我写了an answer .

然而,another answer说,这不是 UB。

我在阅读或理解标准语言时哪里出错了?


注:我看过this thread已经,但我不能下结论。

最佳答案

让我们假设这个上下文:

int main(void) {
    return;
}

和托管实现。

请注意,void main() 并不是严格禁止的(一个实现允许它),并且 return; 在这样的定义中将是完全有效的 主要

首先,这个 return; 显然违反了约束。它违反了N1570 6.8.6.4p1:

A return statement without an expression shall only appear in a function whose return type is void.

(这不是 C90 中的约束违规;在 C99 中已更改。)

该标准要求编译器对包含违反约束或语法规则的任何程序发出至少一个诊断。一旦完成,它就可以继续生成可执行文件(如果诊断是非致命警告)。

尚不清楚是否存在违反约束的程序具有未定义行为的一般规则。该标准没有明确说明。它将“约束”定义为

restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted

我自己的解释是,如果违反约束,则没有有效的解释,因此行为是未定义的,但有些人不同意。我希望在未来的标准中看到对此效果的明确声明。

我认为 C 标准的措辞在这一点上确实含糊不清。

如果没有这样的通用规则,则不清楚该行为是否未定义。在声明此代码违反的约束后,标准继续定义 return 语句的语义:

A return statement terminates execution of the current function and returns control to its caller.

即使在违反约束的情况下,该描述仍然有意义。可以合理地假设,虽然没有完全说明,return; 相当于到达结束 ,相当于 return 0; (这是 main 的特例规则;N1570 5.1.2.2.3)。

另一方面,描述是否明确并非 100% 清楚。 return; 等同于到达结束 的论点特别薄弱。因此,即使没有一般规则,也可以争辩说行为未被遗漏定义(没有行为的定义)。

return; 显然违反了约束,在我看来如果实现生成可执行文件,它具有未定义的行为。当然,符合标准的编译器也可以完全拒绝该程序;在这种情况下,它根本没有任何行为。

底线:将 return; 更改为 return 0 要容易得多 much much ; 而不是回答这个问题。

我鼓励其他语言的律师反驳这个答案。我在这里提出了足够多的内部不一致的论点,应该不会太难。

关于c - 运行从代码生成的二进制文件是否具有 "constraint violation"实际上未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41149194/

相关文章:

c - C 标准库中包含什么?

c - 如何在c中打印特定数据?

c - 如何删除相同的数字并移动数组以在c中删除它们

c++ - 如何使用 libjpeg 将 YUYV 原始数据压缩为 JPEG?

c - 让 ENTER 前进到 GTK3 输入字段中的下一个字段

c++ - 为什么不的unique_ptr在C++ 20 equality_comparable_with nullptr_t?

c++ - UB 何时发生,是否会取消所有先前订立的契约(Contract)?

c - c中的段错误

c++ - 应该在带花括号的 return 语句中调用什么构造函数?

c++ - 转换运算符的外部定义的编译器差异