C++ 条件运算符中的未定义行为
我必须分享这一点: 我因以下涉及条件运算符的小错误被挂断了整整两天 这很容易纠正,但我想知道:C++ 条件运算符中的未定义行为,c++,iterator,valgrind,undefined-behavior,conditional-operator,C++,Iterator,Valgrind,Undefined Behavior,Conditional Operator,我必须分享这一点: 我因以下涉及条件运算符的小错误被挂断了整整两天 这很容易纠正,但我想知道: 为什么要编译错误代码 虫子在干什么 为什么这么难找到 错误代码: std::map<int, some_class> my_map; int key_ctr = 0; //... std::map<int, some_class>::iterator it_next = ke
std::map<int, some_class> my_map;
int key_ctr = 0;
//...
std::map<int, some_class>::iterator it_next =
key_ctr == 0 ?
it_next = my_map.begin() // BUG!!!
:
it_next = --my_map.end(); // BUG!!!!
// .....
这是完全没有帮助的,并指出我在错误的董事(我认为我是分配太多的堆,不知何故)
再说一遍
实际上,您可以将范围缩小到:
It it_next = it_next = whatever;
不管是什么都不重要。重要的是,在执行完整语句之前(;
),它的下一步是未初始化的。这就是问题所在
It it_next = ...
第二部分试图做到但是首先,它尝试评估右侧的内容。哪个是it\u next=Which
。它调用it\u next.operator=(无论什么)
。因此,您正在对未初始化的对象调用成员函数。这是未定义的行为。Ta大哥
3) 所有未定义的行为都很难追踪。这就是为什么你至少应该意识到常见的情况
3为什么这么难找到
因为你没有打开编译器警告
$ g++ -std=c++0x -pedantic -Wall -Werror -g m.cc -o m
cc1plus: warnings being treated as errors
m.cc:10: error: operation on ‘it_next’ may be undefined
m.cc: In function ‘void __static_initialization_and_destruction_0(int, int)’:
m.cc:6: error: operation on ‘it_next’ may be undefined
make: *** [m] Error 1
这个标题有点误导人。问题不在于三元运算符,而在于使用未初始化的变量。严重缺少括号。不是开玩笑。@DavidRodríguez dribeas哪个是未初始化的变量?@john刚刚编辑了我的答案来解释。我喜欢这部分——“为什么要编译错误代码?”。如果你想出了一个编译器,而它没有编译错误代码,你将是一个亿万富翁。什么是未定义的行为
it_next
由三元运算符中的两个表达式赋值,然后执行自赋值。“我看不到UB。”卢钦格里戈谢谢你的解释。这真的很棘手。我并不奇怪OP感到有点委屈。我没有注意到非POD位。gcc也抱怨inta=a=10代码>。但在本例中,情况更糟,因为迭代器是一个UDT,而不是一个原始指针(我一直认为它是)ᵩ, 我的程序相当大,涉及大量的库。因此,-Werror
将导致来自外部库(我无法控制)的警告导致编译崩溃。但我无法修复这些问题,因为它们位于外部库中。@Matthew Clang有一个很棒的-Wno system headers
命令行参数,使其不会从指定为-issystem/path/to/library
的任何目录中的文件生成警告。我希望其他编译器也有类似的功能。
It it_next = it_next = whatever;
It it_next = ...
$ g++ -std=c++0x -pedantic -Wall -Werror -g m.cc -o m
cc1plus: warnings being treated as errors
m.cc:10: error: operation on ‘it_next’ may be undefined
m.cc: In function ‘void __static_initialization_and_destruction_0(int, int)’:
m.cc:6: error: operation on ‘it_next’ may be undefined
make: *** [m] Error 1