c++ - 限制未定义行为引起的困惑?

标签 c++ language-agnostic undefined-behavior

根据我的阅读理解,未定义行为是在编译时为编译器留下几个不同的替代方案的结果。然而,这是否意味着如果遵循严格的编码实践(比如将每个赋值和每个相等放在一个单独的语句中,适当的调试和评论)那么它不应该在寻找未定义的来源方面造成重大问题-行为。

此外,对于出现的每个错误,如果您识别代码,您应该知道可以使用哪些语句来代替该特定语句,对吗?

编辑:我对您编写了您不想编写的代码的地方不感兴趣。我对按数学逻辑合理的代码无法运行的示例感兴趣。

此外,我认为“良好的编码习惯”是每隔几行提供大量信息的注释、适当的缩进和定期调试转储。

最佳答案

未定义的行为不一定会给编译器留下多种选择。最常见的是,它只是在做一些没有意义的事情。

例如,拿这段代码:

int arr[2];
arr[200] = 42;

这是未定义的行为。这并不是说编译器有多种选择可供选择。只是我在做什么没有意义。理想情况下,它一开始就不应该被允许,但是如果没有潜在的昂贵的运行时检查,我们不能保证我们的代码中不会发生这样的事情。所以在 C++ 中,规则很简单,即语言只指定遵守规则的程序的行为。如果它像上面的例子那样做了一些错误的事情,它只是 undefined 应该发生什么。

现在,想象一下您将如何检测此错误。它将如何浮出水面?它可能永远似乎不会引起任何问题。也许我们只是碰巧写入映射到进程的内存(因此我们不会遇到访问冲突),但从未被其他方式使用(因此程序的其他部分不会读取我们的垃圾值,或覆盖我们写入的内容).这样程序就会看起​​来没有错误并且运行良好。

或者它可能命中一个甚至没有映射到我们进程的地址。然后程序会立即崩溃。

或者它可能命中映射到我们进程的地址,但稍后将用于某些事情。那么我们所知道的是,迟早,从该地址读取的函数会得到一个意想不到的值,而且它会表现得很奇怪。该部分很容易在调试器中发现,但它没有告诉我们任何有关何时 或从何处 写入垃圾值的信息。因此,没有简单的方法可以将错误追溯到其源头。

关于c++ - 限制未定义行为引起的困惑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2046952/

相关文章:

c++ - 我可以在不调用未定义行为的情况下存储指向不存在数据的指针吗?

c++ - 在内存映射中使用 reinterpret_cast 时处理未定义的行为

c++ - Boost ASIO 示例无法构建

c++ - 在 Visual C++ 中,如何从返回类型为 map 的函数返回 null?

c++ - 对指针进行解引用并存储指向所指向数据的引用,然后获取引用的地址并对其进行指针算术运算。 C++

algorithm - 递归查找从0到n的个数

validation - 领域驱动设计 - 跨不同聚合的命令的复杂验证

c++ - 为什么编译器资源管理器上的 Visual Studio 忽略异常模型设置?

c++ - error_complexity 使用标准正则表达式,如何增加允许的搜索操作复杂性?

language-agnostic - Code Golf : Conway's Game of Life