c - “未定义的行为”和“实现定义的行为”之间有什么区别,或者为什么要区分它们?
问题描述
C 标准 (AFAIK) 使用这两个术语。我很难理解两者之间的区别在哪里。
如果我有任何给定的、语法正确的 C 语句,编译器不可能不发出一些机器指令。当然,它可以选择根本不发布任何声明,但即使这样也会“依赖于实现”。
一个更具体的例子:整数值溢出。现在我们有两种类型的溢出:算术溢出和内存溢出。如果有符号整数的溢出按照标准是UB,那是什么意思呢?实现是否可以简单地将溢出位溢出到 MSB 的相邻字节中?(从未见过,但可以吗?)
在我看来,“未定义的行为”总是依赖于实现。或者,换句话说,编译器似乎无法在不引入“实现定义”行为的情况下处理任何“未定义行为”。
那么为什么还要区分两者呢?
解决方案
主要区别在于定义了实现定义的行为。也就是说,对于标准中说“实现定义”的每个要求,C 实现都应该附带对该行为的解释。
例如,这里是关于 C 语言实现定义行为的 GCC 文档。
此外,在许多情况下,“实现定义”允许对许多特定可能行为之一做出决定。但是“未定义的行为”总是允许实现做任何事情,无论是在编译时还是在运行时。
另请阅读 Lattner 的博客What Every Programmer Should Know About Undefined Behavior。
推荐阅读
- r - 使用 R 管道时,没有适用于“c('fseq','function')”类对象的“tbl_vars”方法
- r - 直接使用 mgcv 包中的 gam 和使用包装器时获得不同的结果(插入符号中的训练函数)
- laravel - laravel 邮件队列给出意外的 ErrorException
- python - Python TypeError:当脚本单独运行时,字符串索引必须是整数
- linux - 我如何在 linux 中获得没有 sudo 的 pid
- python - 计算列表中每 n 个元素
- javascript - 通过每个级别上的单独条件查找嵌套的对象数组以进行匹配
- fullcalendar - 如果完整日历 5 中有事件,如何设置全天的背景颜色
- html - 允许任何人从 html 文件将数据保存到 amazon-ec2 linux 实例上的 apache 服务器
- r - as.h2o 错误编码特殊字符