C++中int类型异常捕获原理及代码执行顺序等技术疑问
解答你的两个C++异常处理疑问
先把你的代码和运行结果整理出来,方便大家理解问题:
代码示例
int main() { try { throw -1; } catch (int& x) { std::cerr << "We caught an int exception with value: " << x << std::endl; } std::cout << "Continuing on our merry way." << std::endl; return 0; }
运行结果
/tmp$ ./program.out Continuing on our merry way We caught an int exception with value: -1
接下来逐个解答你的疑问:
1. 为什么catch (int& x)能捕获throw -1?普通场景下非const左值引用不能绑定右值啊?
这是C++异常处理机制里的一个特殊规则,和普通的引用绑定逻辑不一样。
通常来说,非const左值引用(比如int&)确实不能直接绑定像-1这样的右值临时对象,但在异常处理的场景中,C++标准网开一面:当你抛出一个临时对象时,catch子句里的非const左值引用可以直接绑定到这个临时的异常对象,而且这个临时对象的生命周期会被延长到catch块执行结束。
这个设计的目的是允许你在catch块里修改异常对象(虽然你这里没这么做),同时保证异常对象在整个catch处理过程中都有效。所以你这里的int& x能成功绑定到抛出的-1临时值是完全符合标准的。
2. 为什么std::cout的输出反而比std::cerr先显示?
这和两个流的缓冲机制以及操作系统的处理方式有关:
std::cout是标准输出流,默认是行缓冲模式:当输出内容里包含std::endl时,会立即刷新缓冲区,把内容输出到终端。std::cerr是标准错误流,默认是无缓冲模式:理论上写入的内容应该立即显示在终端。
但你看到的顺序颠倒,本质上是因为这两个流是独立的,操作系统对它们的输出调度可能存在异步性。比如,有些终端环境下,标准输出的内容可能被优先渲染,或者标准错误的输出因为某些底层原因出现了微小的延迟,导致视觉上看起来std::cout的内容先出来。
实际上程序的执行顺序是:先进入catch块执行std::cerr的输出,再执行std::cout的输出。如果想要严格保证输出顺序和代码执行顺序一致,可以在程序开头加上std::ios_base::sync_with_stdio(true);,强制让C++的流和C标准库的流同步,这样就能避免这种顺序颠倒的问题。
内容的提问来源于stack exchange,提问作者Ghasem Ramezani
相关产品推荐
相关产品推荐

