Visual Studio 2019下C++流实现异常行为:哪种表现合规?
std::streambuf实现的标准合规性分析
首先看测试代码:
#include <iostream> #include <sstream> class mystreambuf : public std::streambuf { int_type underflow() override { // [27.6.3.4.5/6] ... 'or throws an exception if the function fails' throw std::runtime_error("here"); } }; int main() { mystreambuf rdbuf; std::ostringstream os; std::cout << "State: " << os.exceptions() << std::endl; try { os << &rdbuf; std::cout << "No except: " << os.good() << std::endl; } catch (std::runtime_error const&) { std::cout << "With except: " << os.good() << std::endl; } return 0; }
不同环境的输出差异
- GCC/Linux环境输出:
State: 0 No except: 0 - Visual Studio 2019环境输出:
State: 0 With except: 0
标准合规性分析
根据C标准(以C17为例,[ostream.inserters]/3条款),对std::basic_ostream::operator<<(std::basic_streambuf*)的行为有明确规定:
当从传入的streambuf读取字符时,如果调用
sbumpc()或sgetc()(二者会间接调用underflow())抛出异常,函数会先在输出流中设置badbit状态位,再检查流的异常掩码:若掩码包含badbit则重新抛出异常;否则不传播异常,函数正常返回。
测试代码中os.exceptions()输出为0,说明输出流的异常掩码未设置任何标志(包括badbit)。按标准要求,operator<<应当捕获underflow()抛出的异常,设置badbit后返回,不会让异常传播到外部try-catch块中。
因此GCC的行为符合C++标准,而Visual Studio 2019的行为不符合标准要求——它未按规定捕获并处理underflow()抛出的异常,导致异常直接传播到了外部。
内容的提问来源于stack exchange,提问作者malat
相关产品推荐
相关产品推荐

