c++ - 比较 boost::system::error_category

标签 c++ boost-asio boost-system

以下比较失败,错误为 errorCode.category().name() 输出“asio.misc”,为 errorCode.message() 输出“文件结尾”

如果它声称属于 asio.misc 类别,那么为什么 (errorCode.category() == boost::asio::error::misc_category) 的 if 条件评估为 false?

谷歌搜索(包括此处的答案)说 boost::system::error_code 可以在多个类别中具有相同的值,因此我假设为了获得正确的消息和含义,我们必须比较 boost::system::error_category 以及 boost::system::error_code::value。

如果这不起作用,我们如何正确比较类别?

有问题的代码:

//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    if( errorCode.category() == boost::asio::error::misc_category )
    {
        switch (errorCode.value())
        {
        case boost::asio::error::eof:
            debugMsg << ". Server has disconnected.";
            break;
        case boost::asio::error::connection_refused:
            debugMsg << ". Connection Refused";
            break;
        default:
            debugMsg << ". Unknown Error.";
            break;
        }
    }
    else
    {
        debugMsg << ". Unknown Error category.";
    }

    return debugMsg.str();
}

编辑:

根据 https://theboostcpplibraries.com/boost.systemBoost::file_system: Checking error codes

人们通常错误地编写代码只比较错误值而不是类别。单独的错误值不是唯一的,可能出现在多个类别中。用户还可以自由创建自己的错误代码和类别。因此,两者必须进行比较。我认为这不会影响大量应用程序,因为它们无论如何都只使用一个功能或库来提升他们的项目和/或大多数错误代码都映射到 Windows 错误代码,而 Windows 错误代码已尽力避免碰撞。

我不得不在另一台电脑上访问 boost 邮件列表,因为我的工作几乎阻止了一切。

http://boost.2283326.n4.nabble.com/Compare-boost-system-error-category-td4692861.html#a4692869

据那边的一位 friend 说,比较失败的原因是因为boost库是静态链接的,boost::system::error_category::operator ==比较地址,所以LHS是一个库中的地址RHS 是另一个地址。它们不会像预期的那样相等。

使用 operator == 的地址对我来说似乎是一个非常愚蠢的举动。如果发现任何新知识,我将继续在 boost 邮件列表上大肆宣扬,并在这里为其他人编辑。

现在,我动态链接并使用表单

//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    // IMPORTANT - These comparisons only work if you dynamically link boost libraries
    //             Because boost chose to implement boost::system::error_category::operator == by comparing addresses
    //             The addresses are different in one library and the other when statically linking.
    //
    // We use make_error_code macro to make the correct category as well as error code value.
    // Error code value is not unique and can be duplicated in more than one category.
    if (errorCode == make_error_code(boost::asio::error::connection_refused))
    {
        debugMsg << ". Connection Refused";
    }
    else if (errorCode == make_error_code(boost::asio::error::eof))
    {
        debugMsg << ". Server has disconnected.";
    }
    else
    {
        debugMsg << ". boost::system::error_code has not been mapped to a meaningful message.";
    }

    return debugMsg.str();
}

但是,当我静态链接到 boost 时,这不起作用。如果有人对我们如何正确比较 boost::system::error_code 并获得预期结果有更多建议,请让我们深入了解这一点。

最佳答案

C++ 11 标准暗示每个错误类别实例都应具有 全局唯一地址和平等比较应使用 地址进行比较。不幸的是,这在可移植设备中并不可靠 代码,只有 Dinkumware STL 实现了真正的地址唯一性 过程中的任何地方,它都增加了一个完整的内存屏障来实现 也就是说,它很贵。

Boost的实现质量与libstdc++或libc++一样, 在某些情况下你可以获得多个实例化 可以有不同的地址。

在我自己的代码中,我先做比较运算符,如果失败了我 对类别的 name() 执行 strcmp()。到目前为止,这还没有困扰我。 我个人认为错误类别的这个方面是 标准中的缺陷,如指定的那样,它强制使用非 header 如果您希望它符合要求,则实现,即使那样也不 覆盖 RTLD_LOCAL 这意味着你需要回到命名共享 内存或一些 hack。

关于c++ - 比较 boost::system::error_category,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42983330/

相关文章:

c++ - errc::timed_out 类型的 boost 系统 make_error_code 具有 "Unkown error"消息

linux - 如何在 Visual Studio 2017 中为跨平台 Linux 项目链接 Linux 库?

c++ - Boost 系统 1.69.0 不只是标题?

c++ - 模板推导 : const reference and const pointer

c++ - 如何 - 从文本文件中读取特定的行集

c++ - 提升::亚西欧。消息在哪个线程中发送?

c++ - 如何在 Windows 上停止 boost::ioservice

c++ - 在不释放所有动态分配的资源的情况下结束程序是否有风险?

c++ - 在继承的情况下,每个类的静态数据成员是否唯一?

c++ - 在 C++/Boost ASIO 中内联 ntohs()/ntohl()