Compilation issue related to Boost include order

Issue #233 resolved
Frank Drop created an issue

Using Blaze 3.5 (same issue occurs for earlier version) Using libboost-dev 1.65.1.0ubuntu1

When compiling the following:

#include <boost/asio.hpp>
#include <blaze/Blaze.h>
#include <blaze/math/Subvector.h>
#include <blaze/math/Row.h>
#include <blaze/math/Column.h>

int main(int argc, char** argv)
{
 }

I get many errors, with the first errors being:

In file included from /usr/include/termios.h:39:0,
                 from /usr/include/boost/asio/serial_port_base.hpp:25,
                 from /usr/include/boost/asio/basic_serial_port.hpp:29,
                 from /usr/include/boost/asio.hpp:26,
                 from /home/fdrop/projects/controller_wrapper/src/Main.cpp:10:
/home/fdrop/projects/blaze/blaze/math/expressions/Forward.h:189:20: error: expected nested-name-specifier before numeric constant
 template< typename VT1, typename VT2, bool TF >
                    ^
/home/fdrop/projects/blaze/blaze/math/expressions/Forward.h:189:20: error: expected > before numeric constant
In file included from /home/fdrop/projects/blaze/blaze/math/views/Forward.h:44:0,
                 from /home/fdrop/projects/blaze/blaze/math/typetraits/IsBand.h:43,
                 from /home/fdrop/projects/blaze/blaze/math/constraints/Band.h:43,
                 from /home/fdrop/projects/blaze/blaze/math/Band.h:44,
                 from /home/fdrop/projects/blaze/blaze/Math.h:46,
                 from /home/fdrop/projects/blaze/blaze/Blaze.h:43,
                 from /home/fdrop/projects/controller_wrapper/src/Main.cpp:11:
/home/fdrop/projects/blaze/blaze/math/expressions/Forward.h:190:49: error: TF was not declared in this scope
 decltype(auto) operator+( const DenseVector<VT1,TF>&, const DenseVector<VT2,TF>& );

If I interchange the order of the blaze and boost includes, the error disappears. Please excuse me if this is not a bug, but a 'feature' I do not understand.

Comments (6)

  1. Klaus Iglberger

    Hi Frank!

    Thanks a lot for pointing out this potential defect, this is highly appreciated.

    I have taken a closer look at the problem. Unfortunately I could not find the exact source within Boost::asio, but I did realize that via some preprocessor magic the <boost/asio.hpp> header is messing up code in Blaze. The error message you posted involves the following forward declaration from the <blaze/math/expressions/Forward.h>header:

    template< typename VT1, typename VT2, bool TF >
    decltype(auto) operator+( const DenseVector<VT1,TF>&, const DenseVector<VT2,TF>& );
    

    The preprocessor is turning this forward declaration into the following piece of non-compiling code:

    template< typename 
    # 189 "/Users/eagle/blaze/blaze/blaze/math/expressions/Forward.h" 3 4
                      0x00010000
    # 189 "/Users/eagle/blaze/blaze/blaze/math/expressions/Forward.h"
                         , typename VT2, bool TF >
    decltype(auto) operator+( const DenseVector<
    # 190 "/Users/eagle/blaze/blaze/blaze/math/expressions/Forward.h" 3 4
                                               0x00010000
    # 190 "/Users/eagle/blaze/blaze/blaze/math/expressions/Forward.h"
                                                  ,TF>&, const DenseVector<VT2,TF>& );
    

    Apparently VT1 has some special effect within Boost::asio. From my point of view, however, the Blaze code is perfectly correct and the problem lies in the <boost/asio.hpp> header. Again, unfortunately I couldn't identify the exact source of the issue. Since the problem goes away if <boost/asio.hpp> is included after <blaze/Blaze.h> please use this solution.

    Thanks again for creating this issue,

    Best regards,

    Klaus!

  2. Dima Resom

    Hi Klaus,

    currently we are writing a C++ library with a python interface using your blaze library and we encountered a very similar error. On Linux and MacOS systems the <termios.h> belongs to the system it overwrites VT1 which results in a conflict with blaze. See https://github.com/randombit/botan/issues/350 for a similar problem. Unfortunately, this <termios.h> is included by pybind11. A change in the include order "solves" the problem but another real solution would be nicer.

    Cheers, Dima

  3. Klaus Iglberger

    Hi Dima!

    A possible solution for you could be to wrap the <blaze/Blaze.h> include into a separate file:

    #undef VT1
    #include <blaze/Blaze.h>
    

    Of course the list of #undef could be extended for every symbol that causes a naming conflict. Additionally, this file would allow you to provide specific configurations and customizations for Blaze (which you might need anyway; see the wiki). I hope this helps,

    Best regards,

    Klaus!

  4. Klaus Iglberger

    In the context of issue #315 we have discovered that the problem is not the Boost libraries, but several Linux headers (asm/termbits.h, asm-generic/termbits.h and bits/termios.h). Commit 7850cb4 prevents all naming conflicts with the preprocessor symbols VT1 and VT2. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.7.

  5. Klaus Iglberger

    Commit 7850cb4 prevents all naming conflicts with the preprocessor symbols VT1 and VT2. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.7.

  6. Log in to comment