在我的程序中,我发现当I
为int32_t
时,循环无法正确退出。它看起来像整数溢出,远远大于10,循环不会停止。请告诉我发生了什么,以及如何在大型项目中避免这个错误。
#include <iostream>
#include <stdint.h>
int f(int n){
for (int32_t i = 0; i < 10; ++i)
{
int64_t time = 4500000000 + (i) * 500000000;
std::cout << time<< " i: " << i << std::endl;
}
return 0;
}
int main ()
{
return f(10);
}
代码链接
如果使用GCC 11.2.0和-Wall-O2
选项,您将看到一条关于未定义行为的警告:
test.cpp: In function 'int f(int)':
test.cpp:7:42: warning: iteration 5 invokes undefined behavior [-Waggressive-loop-optimizations]
7 | int64_t time = 4500000000 + (i) * 500000000;
| ~~~~^~~~~~~~~~~
test.cpp:5:27: note: within this loop
5 | for (int32_t i = 0; i < 10; ++i)
| ~~^~~~
编译器知道5 * 500000000太大,不适合int
(通常是32位)。有符号整数溢出是C中未定义的行为。因此,编译器可以自由地假设这种溢出永远不会发生,因此它会假设i
永远不会达到10,因此它可以摆脱检查i的for循环部分
只需添加一些强制转换,以指定要执行64位算术。这将消除警告、溢出和未定义的行为:
int64_t time = (int64_t)4500000000 + i * (int64_t)500000000;
更新:对于可能有更多错误的大型项目,您可以考虑使用GCC的
-fwrapv
选项,该选项可以定义有符号整数溢出的行为。如果您的工具链支持这些选项,您也可以使用-fsanitize=signed-integer-overflow
或-fsantisize=un定义
在运行时检测这些问题。
在我的程序中,我发现当为时,循环无法正确退出。它看起来像整数溢出,远远大于10,循环不会停止。请告诉我发生了什么,以及如何在大型项目中避免这个错误。 代码链接
问题内容: 我正在编写代码以确定nxn列表中的每个元素是否相同。即返回true,但将返回false。我正在考虑编写一个代码,当它发现与第一个元素不同的元素时立即停止。即: 我想停止此循环, 然后返回false。否则返回true。我将如何实施呢? 问题答案: 使用和为此。可以使用以下命令在Python中完成打破嵌套循环的操作: 另一种方法是将所有内容包装在函数中,并用于从循环中退出。
我正试图按照下面的代码读取一个txt文件: 我的txt文件如下所示: 当我不使用变量I时,仅用于在控制台打印我的文件,我的代码可以完美地工作。你们能帮我吗?如何将每个数据分离到数组中?我是Java初学者。
问题内容: 我也在学习Java和android。我们可以在while循环中执行的几乎所有事情都可以在while循环中执行。 我发现一个简单的条件,使用while循环比for循环更好 如果我必须在程序中使用counter的值,那么我认为while循环要比for循环好 使用while循环 在这种情况下,我发现while循环要比for循环好,因为如果要在for循环中实现相同的效果,则必须将counter
问题内容: 我正在浏览旧的考试问题(当前是大学一年级),我想知道是否有人可以更彻底地解释为什么以下循环在预期的情况下不会结束。为什么会这样?我了解由于舍入错误或其他原因,它会跳过100.0,但是为什么呢? 问题答案: 数字0.1不能精确地用二进制表示,就像1/3不能精确地用十进制表示一样,因此您不能保证: 这是因为在二进制文件中: 但是,双精度数不能包含无限精度,因此,正如我们将1/3近似为0.3
问题内容: 以下示例在Node.js书中给出: 解释了while循环为何阻止执行时,作者说: 节点将永远不会执行超时回调,因为事件循环卡在了循环中,而循环在第7行开始了,因此永远不会给它处理超时事件的机会! 但是,作者没有解释为什么这是在事件循环的背景下发生的,还是在幕后真正发生了什么。 有人可以详细说明吗?为什么节点卡住?以及如何在保留控制结构的同时更改上述代码,以使事件循环不会被阻塞,并且代码