在变量声明语句中修改变量是否为良定义行为?代码编译差异疑问
这绝对是未定义行为,别被VS2015的表现迷惑了!
首先给你拍板:你写的int i = i=0;完全不属于良定义行为,哪怕VS2015编译没警告还输出0,那也只是编译器的“好心”实现,C++标准根本不保证这个结果稳定。
为啥是未定义行为?
咱用大白话拆解:
- 当你声明
int i的时候,虽然i这个名字在初始化表达式里能被找到,但这时候i还没完成初始化——就像你刚买了个空杯子,还没装水呢,就想着把杯子里的“水”倒回杯子里? - 这个表达式里有两个对
i的操作:右边的i=0是给i赋值,左边的是拿这个赋值的结果去初始化i。关键问题在于,C++标准没规定这俩操作的执行顺序!编译器想先干哪个就干哪个:- 如果先执行
i=0再初始化,那结果是0,就是你看到的情况; - 但如果编译器先去初始化
i,那这时候i还没被赋值,读的是未初始化的内存,结果可能是随机垃圾值,甚至程序崩了都有可能。
- 如果先执行
为啥不同编译器表现不一样?
- VS2015没警告还输出0,只是它的实现默认选了“先赋值再初始化”的顺序,但这不是标准要求的——换个VS版本或者开个更高的优化等级,结果可能就变了。
- 而g++开启
-Wall -Wextra后抛出-Wsequence-point警告,这才是负责任的表现:它在明确提醒你,这段代码的结果没谱,编译器没法保证它能按预期运行。
正确的写法
想把i初始化为0,直接写int i = 0;就完事儿了!简洁、清晰,所有编译器都会按你预期的来,完全没歧义。
内容的提问来源于stack exchange,提问作者choxsword
相关产品推荐
相关产品推荐

