c++ - 使用 Visual Studio 编译代码时,boost::iostreams::multichar_input_filter 中的异常消失

标签 c++ visual-c++ boost boost-iostreams

我正在研究可以解码自定义文件格式的流过滤器。我的目标是使用 boost::iostreams::filtering_istream读取文件并用我的 boost::iostreams::multichar_input_filter 处理它子类,以便我可以使用 << 加载值运营商。

我还希望当我的过滤器无法解码流并抛出异常时终止进程,当我在适用于 Linux 的 Windows 子系统上使用 gcc 5.4 编译代码时会发生这种情况,但异常在它到达我的代码之前被吞没如果我用 VS2017 编译。

我在 Windows 和 WSL 上都使用 Boost 1.68.0;我已经在两个平台上使用 b2 构建并安装了它,没有任何自定义参数或配置。我还在 WSL 上尝试了 1.58.0,它来自包管理器。

该项目使用CMake,我没有在CMakeSettings.json 或launch.vs.json 中自定义任何内容。

我创建了这个简化的代码,展示了我如何使用过滤器链、异常类,以及我如何 try catch 处理错误:

#include <iostream>
#include <boost/iostreams/concepts.hpp>    // multichar_input_filter
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/throw_exception.hpp>

using namespace std;
namespace io = boost::iostreams;

class TestFilterException : public BOOST_IOSTREAMS_FAILURE {
  public:
    explicit TestFilterException(const char* message) : BOOST_IOSTREAMS_FAILURE(message) {
    }
};

class TestFilter : public io::multichar_input_filter {
  public:
    explicit TestFilter() {
    }

    template <typename Source> streamsize read(Source& src, char* output_buffer, streamsize requested_char_count) {
        BOOST_THROW_EXCEPTION(TestFilterException("Something went wrong"));
    }

    template <typename Source> void close(Source&) {
    }
};

int main(const int argc, const char *argv[]) {
    char buffer[64] = {'x'};
    io::array_source source = io::array_source(buffer);

    io::filtering_istream in;
    in.push(TestFilter());
    in.push(source);

    char c;
    try {
        in >> c;
        cout << c;
    } catch (boost::exception& e) {
        cout << "Expected exception";
        return 1;
    }
    return 0;
}

我希望此代码将“预期异常”消息写入输出并退出并返回代码 1在所有平台上。但是,当我用 Visual Studio 编译它时,它会输出一些垃圾并返回代码 0 .

最佳答案

我认为这是旧版 gcc 中的错误。较新的 gcc 和 VS 正确捕获抛出的异常并设置坏位标志,而不是通过流方法传播异常。打印垃圾是因为 c 在读取尝试失败后未初始化。您可以通过在流中设置异常标志使流抛出错误位异常:

try
{
    io::filtering_istream in;
    in.exceptions(::std::ios_base::badbit | ::std::ios_base::failbit | ::std::ios_base::eofbit);
    in.push(TestFilter());
    in.push(source);
    char c;
    in >> c;
    cout << c;
} catch (boost::exception& e) {
    cout << "not expected boost exception";
    return 1;
}
catch(::std::exception const & e)
{
    cout << "Expected std exception";
    return 2;
}

另见 iostream Exceptions documentation

关于c++ - 使用 Visual Studio 编译代码时,boost::iostreams::multichar_input_filter 中的异常消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54254063/

相关文章:

c++ - SubclassWindow() 函数断言

c++ - 为什么会出现 "constant too large"错误?

c++ - 如何从文件中读取并动态分配一个int数组

c++ - boost::scoped_ptr 到引用的转换失败

c++ - dijkstra 的恒权最短路径算法

c++ - 如何以惯用的方式实现 C++ 序列化程序?

c++ - 检查 boost 属性树中的值是树还是终端值

c++ - LLVM 段错误/需要使用指令而不是指令*

c++ - 在模板参数的函数中使用一个或另一个命名空间

c++ - Opencv CAP_PROP_FRAME_COUNT 返回负大数