Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 添加调试输出时,循环结果不同(Heisenbug?)_C++ - Fatal编程技术网

C++ 添加调试输出时,循环结果不同(Heisenbug?)

C++ 添加调试输出时,循环结果不同(Heisenbug?),c++,C++,如果在循环中添加调试输出,则循环的行为会有所不同。我想知道这是编译器错误,还是我错误地依赖于一些未定义的C++行为。 循环从uint64_t数组中读取整数,将它们存储在临时数组中,然后对条目求和。由于我掌握的数据,我预计总和将大于60 如果小于60,我会重新尝试相同的循环,这次添加调试输出。我希望得到同样的小于60的结果,但现在我得到了大于60的结果 uint64_t test[8]; for(int i=0; i<8; i++) { test[i] = overflow[inde

如果在循环中添加调试输出,则循环的行为会有所不同。我想知道这是编译器错误,还是我错误地依赖于一些未定义的C++行为。 循环从uint64_t数组中读取整数,将它们存储在临时数组中,然后对条目求和。由于我掌握的数据,我预计总和将大于60

如果小于60,我会重新尝试相同的循环,这次添加调试输出。我希望得到同样的小于60的结果,但现在我得到了大于60的结果

uint64_t test[8];
for(int i=0; i<8; i++) {
    test[i] = overflow[index + i];
}
int temp[64];
int count2 = 0;
for(int j = 0; j < 64; j++) {
    int cj = (int) ((test[j / 8] >> (8 * j)) & 0xff);
    count2 += cj;
    temp[j] = cj;
}
if (count2 < 60) {
    int count3 = 0;
    for(int j = 0; j < 64; j++) {
        int cj = (int) ((test[j / 8] >> (8 * j)) & 0xff);
        temp[j] = cj;
        ::std::cout << " foo\n";
        count3 += cj;
    }
    ::std::cout << "count2 " << count2 << " count3 " << count3 << "\n";
}
如果循环从0到63,则循环的方向与相同的结果无关。只有一根线。如果我在第二个循环中对cout进行注释,我会得到一些原始的、意外的情况,例如count2 4 count3 4。只要我在循环中做任何形式的cout甚至foo,我就会得到count2!=再数三下。我试图使第一个循环更加复杂,不必要地将cj乘以100,但结果相同

Makefile中的编译器选项:

OPT = -O3 -DNDEBUG -march=native
CXXFLAGS += -fno-strict-aliasing -Wall -std=c++11 $(OPT)
LDFLAGS = -Wall
LLVM和g++的结果相同


<问题> -O2- G++,在C++和C中没有尝试LLVM .< /P> < P>,在任何方向上移位k位整数超过k-1位是未定义的。p> 因此,当j>=8时,溢出[index+j/8]>>8*j是未定义的,这显然会在两个循环中导致非常不同的行为

我认为这应该会产生预期的结果:

int temp[64] = {0};
for(int j = 0; j < 8; j++) {
    int cj = (int) ((test[j / 8] >> (8 * j)) & 0xff);
    count2 += cj;
    temp[j] = cj;
}

你能不能把这个问题仔细考虑一下?什么是索引?什么是count3?您是否有点讽刺地超出了溢出所指向的缓冲区的界限?当然,我理解您希望有一个最小的测试用例。。。我可能会,但会有很多工作要做。但是很抱歉代码中的错误,count3是一个新的整数。。。修好了。如果超出范围有关系吗?不可能有那么多工作。显示如何分配溢出,以及索引是什么。您不必在实际案例中显示使用复杂业务逻辑计算的代码。只需在此处显示该业务逻辑的结果。例如,int index=57;//由实际代码中的业务逻辑计算。如果这不再重现问题,你会得到一个提示,问题出现在被省略的部分,而不是问题的代码中。当然,如果你超出了范围,那就很重要了。访问您不拥有的内存(如超出动态分配数组的范围)是未定义的行为,即错误和任何情况都可能发生。当j>=8时,溢出[index+j/8]>>8*j是未定义的。
int temp[64] = {0};
for(int j = 0; j < 8; j++) {
    int cj = (int) ((test[j / 8] >> (8 * j)) & 0xff);
    count2 += cj;
    temp[j] = cj;
}