BOOST_ERROR_CODE_HEADER_ONLY does not have the adv

2020-04-10 02:36发布

问题:

In my app I include boost/system/error_code.hpp (boost 1.58) but don't want to link to boost_system, but instead have a header-only solution. I read by defining BOOST_ERROR_CODE_HEADER_ONLY that should be possible. But unfortunately, it does not work as expected. I still get a linker error for boost::system::system_category().

I wonder if that is supposed to work at all and if so how. The code in the boost header is:

# ifdef BOOST_ERROR_CODE_HEADER_ONLY
    inline const error_category &  system_category() BOOST_SYSTEM_NOEXCEPT;
    inline const error_category &  generic_category() BOOST_SYSTEM_NOEXCEPT;
#else
    BOOST_SYSTEM_DECL const error_category &  system_category() BOOST_SYSTEM_NOEXCEPT;
    BOOST_SYSTEM_DECL const error_category &  generic_category() BOOST_SYSTEM_NOEXCEPT;
#endif

and as you can see there is no body defined for system_category(). How can this work at all without linking to a lib?

Update:

In the meantime I found where the body of that declaration is defined (in boost/system/detail/error_code.hpp which is included by the boost/system/error_code.hpp file. Still it does not avoid the linker errors. I'm working in XCode (llvm C++11) and have defined BOOST_ERROR_CODE_HEADER_ONLY in the target settings, if that matters.

回答1:

I got it to work after some experimenting. The key for success here is to include the header boost/system/error_code.hpp before any other code that includes that header as well, with the BOOST_ERROR_CODE_HEADER_ONLY preprocessor symbol defined directly before the include, in a cpp file. It is essential to include it in a cpp file and not, e.g. in a precompiled header (stdafx.h, *_prefix.h etc.) because it includes code, which only works in an object file. Defining BOOST_ERROR_CODE_HEADER_ONLY at project/target level might work too, but since you only need this exactly once in your entire project/target it makes more sense to defined that right before you include the boost header the first time.

If you follow this rule you will also not be affected by a duplicate symbol problem that may occur if you include the same system_category() code in multiple cpp files.

You may still get problems when you compile your code in release mode, as the compiler may automatically remove the included code (if not used in that cpp file). So it's better to disable optimization for it. However, since you don't want that for your regular code, it makes sense to create an own cpp file just for this include and disable optimization for that file entirely. This is how I ended up finally.



标签: c++ boost xcode6