《C++ Primer 5th》switch语句变量初始化规则相关疑问求证
你的猜想完全正确,《C++ Primer 5th》示例里的注释表述确实存在因果倒置的问题。
根据C++标准规则,switch语句中控制流跳转时,不允许跳过带有非平凡初始化的自动存储期变量的定义点:
std::string的默认构造函数是非平凡的,定义string file_name;时会隐式执行初始化操作。如果允许控制流直接跳转到case false,那么处于同一作用域内的file_name已经完成作用域声明,但初始化步骤被跳过,这属于语法错误,编译器会直接抛出编译错误,根本不会允许代码运行到后续访问file_name的步骤。原注释的表述颠倒了因果:不是因为跳过了隐式初始化的变量导致变量未初始化,而是因为这个变量会执行隐式初始化,所以标准根本不允许跳过它的定义。- 你的测试用例刚好验证了这条规则:自定义的
Foo是平凡默认可构造类型,定义Foo f;时不会执行任何实际的初始化操作,所以编译器允许控制流跳过它的定义。这种情况下代码可以编译通过,只是后续在case 2中访问f的行为属于未定义行为,不会触发编译错误。
如果需要在switch的case分支内定义非平凡初始化的变量,可以给分支增加单独的块作用域,把变量定义在块内,这样跳转时不会跨过变量的作用域边界,就不会触发编译错误:
case true: { string file_name; // 定义在块作用域内,不会影响其他分支 // 其他逻辑 } break; case false: // 此处file_name已经超出作用域,不存在访问风险
内容的提问来源于stack exchange,提问作者Itachi Uchiwa
相关产品推荐
相关产品推荐

