我怀疑我发现了一个g ++优化错误,它涉及取消引用具有负索引的对象(结构体)中的数组。g ++ 4.8.5具有负数组索引的循环优化错误
在下文中,节点是结构,其具有阵列前述它(在我的实际代码它是一个跳跃列表,其中它的两个数的指针和其数据包的大小是可变的和未知的节点底层的SkipList代码,因此决定将指针放在对象引用和数据包之前 - 在这个对象之后的这段时间很长)。
#include <iostream>
#include <stdlib.h>
class Node {
public:
unsigned int ptr[1]; // really an array going backwards
long datum; // This seems to be necessary for the bug to surface
};
class NodeList {
public:
Node* hdr;
NodeList() {
void* p_v = malloc(sizeof(Node) + 32 * sizeof(unsigned int));
hdr = (Node*)((char*)p_v + 32 * sizeof(unsigned int));
hdr->ptr[-5]=100;
}
void setNodes() {
int nn=0;
while(rand() > 20 && nn<9) {
nn++;
}
if(nn < 9) {
nn = 9;
}
// It is a logical truth that nn = 9 here
//nn = 9; // IF THIS IS UNCOMMENTED EVERYTHING WORKS!
std::cout << "nn=" << nn << " (should be 9) " << std::endl;
int ctr = 0;
for(int i=0; i<=nn; i++) {
ctr++;
hdr->ptr[-i]=0;
}
std::cout << "ctr was incremented " << ctr << " times (should be 10) and hdr->ptr[-5] = " << hdr->ptr[-5] << " (should be 0)\n";
}
};
int main(int argc, char** argv) {
NodeList list;
list.setNodes();
}
预期输出具有CTR递增10次,HDR-> PTR [-5]为0优化代码只是通过循环一次进入(即不循环),和叶ptr-> HDR [ - 5]为100.这是一个错误。
-fno-aggressive-loop-optimizations似乎可以解决它,但显然如果输出代码是正确的话会更好。
我把这里放在这里(a)得到验证,这是一个错误,因为我是一个新手,这是我的第一个问题,(b)询问任何熟知gcc dev社区的人应该怎么做它(例如,我应该如何报告它,以及它是否在后来的版本中得到修复),以及(c)允许在CentOS 7(或任何其他4.8版本的发行版)上经历过这个最令人沮丧和耗时的问题的人,看到确认他们已经击中了同胞患者的错误!
对(C风格)数组不使用负指数是未定义的行为? – nefas
不,对于* all * n(正数和负数),'arr [n]'被定义为'*(arr + n)'。当然,要确保参考是正确分配的内存。见[这个问题](https://stackoverflow.com/q/3473675/8084766) – galois99
[这个问题](https://stackoverflow.com/questions/3473675/are-negative-array-indexes-allowed-in- c)可能有你想要的答案。 – nefas