根据我的阅读理解,未定义行为是在编译时为编译器留下几个不同的替代方案的结果。然而,这是否意味着如果遵循严格的编码实践(比如将每个赋值和每个相等放在一个单独的语句中,适当的调试和评论)那么它不应该在寻找未定义的来源方面造成重大问题-行为。
此外,对于出现的每个错误,如果您识别代码,您应该知道可以使用哪些语句来代替该特定语句,对吗?
编辑:我对您编写了您不想编写的代码的地方不感兴趣。我对按数学逻辑合理的代码无法运行的示例感兴趣。
此外,我认为“良好的编码习惯”是每隔几行提供大量信息的注释、适当的缩进和定期调试转储。
最佳答案
未定义的行为不一定会给编译器留下多种选择。最常见的是,它只是在做一些没有意义的事情。
例如,拿这段代码:
int arr[2];
arr[200] = 42;
这是未定义的行为。这并不是说编译器有多种选择可供选择。只是我在做什么没有意义。理想情况下,它一开始就不应该被允许,但是如果没有潜在的昂贵的运行时检查,我们不能保证我们的代码中不会发生这样的事情。所以在 C++ 中,规则很简单,即语言只指定遵守规则的程序的行为。如果它像上面的例子那样做了一些错误的事情,它只是 undefined 应该发生什么。
现在,想象一下您将如何检测此错误。它将如何浮出水面?它可能永远似乎不会引起任何问题。也许我们只是碰巧写入映射到进程的内存(因此我们不会遇到访问冲突),但从未被其他方式使用(因此程序的其他部分不会读取我们的垃圾值,或覆盖我们写入的内容).这样程序就会看起来没有错误并且运行良好。
或者它可能命中一个甚至没有映射到我们进程的地址。然后程序会立即崩溃。
或者它可能命中映射到我们进程的地址,但稍后将用于某些事情。那么我们所知道的是,迟早,从该地址读取的函数会得到一个意想不到的值,而且它会表现得很奇怪。该部分很容易在调试器中发现,但它没有告诉我们任何有关何时 或从何处 写入垃圾值的信息。因此,没有简单的方法可以将错误追溯到其源头。
关于c++ - 限制未定义行为引起的困惑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2046952/