MinGW和Clang默认行为不同导致程序逻辑差异的问题

我们知道,在C/C++的众多编译器实现中,有些标准中没有规定的行为可能是有差异的,这不,今天在写数据结构实验的时候就遇到了MinGW和Clang默认行为不同而导致的程序逻辑谬误

问题复现

由于完整代码很长,这里就不全部放出来了,只放出问题的部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class BSTNode{
public:
BSTNode* lc;
BSTNode* rc;
int size;
int data;
BSTNode(int data);
BSTNode(int data[], int length);
void levelTravel();
void midTravel();
void preTravel();
};

BSTNode::BSTNode(int data[], int length){
if(length <= 0){
throw "Illegal Parameter!";
}
this->size = 1;
this->data = data[0];
BSTNode* cur;
BSTNode* pre;
for(int i = 1; i < length; i++){
cur = this;
pre = NULL;
// 插入节点
while(true){
pre = cur;
if(cur->data > data[i]){
cur = cur->lc;
if(cur == NULL){
pre->lc = new BSTNode(data[i]);
size++;
break;
}
}
else if(cur->data < data[i]){
cur = cur->rc;
if(cur == NULL){
pre->rc = new BSTNode(data[i]);
size++;
break;
}
}
else{
// 忽略相同的数值
break;
}
}
}
}

上述代码在clang 15.0.0上编译运行是没问题,但是在mingw 14.2.0上运行会无限循环,在继续阅读之前可以先看看代码思考一下。

可以看到这是个BST的构造函数,在构造函数中,我并没有初始化lcrc,这正是问题所在!在clang中,为初始化的指针会被自动设置为NULL,但是在mingw中,这是未定义的!所以才会导致无限循环。

解决

要解决这个问题,自然就是在进入循环前初始化lcrc

1
2
this->lc = NULL;
this->rc = NULL;