首页 > 解决方案 > “未定义的行为”和“实现定义的行为”之间有什么区别,或者为什么要区分它们?

问题描述

C 标准 (AFAIK) 使用这两个术语。我很难理解两者之间的区别在哪里。

如果我有任何给定的、语法正确的 C 语句,编译器不可能不发出一些机器指令。当然,它可以选择根本不发布任何声明,但即使这样也会“依赖于实现”。

一个更具体的例子:整数值溢出。现在我们有两种类型的溢出:算术溢出和内存溢出。如果有符号整数的溢出按照标准是UB,那是什么意思呢?实现是否可以简单地将溢出位溢出到 MSB 的相邻字节中?(从未见过,但可以吗?)

在我看来,“未定义的行为”总是依赖于实现。或者,换句话说,编译器似乎无法在不引入“实现定义”行为的情况下处理任何“未定义行为”。

那么为什么还要区分两者呢?

标签: cundefined-behaviorimplementation-defined-behavior

解决方案


主要区别在于定义了实现定义的行为。也就是说,对于标准中说“实现定义”的每个要求,C 实现都应该附带对该行为的解释。

例如,这里是关于 C 语言实现定义行为的 GCC 文档。

此外,在许多情况下,“实现定义”允许对许多特定可能行为之一做出决定。但是“未定义的行为”总是允许实现做任何事情,无论是在编译时还是在运行时。

另请阅读 Lattner 的博客What Every Programmer Should Know About Undefined Behavior


推荐阅读