boostorg / core

Boost Core Utilities
133 stars 83 forks source link

Including Boost Python libraries produces C2039 compiler error #130

Open zerovirus123 opened 1 year ago

zerovirus123 commented 1 year ago

I have built Boost_1.76 with the following configurations.

Compiler: MSVC 143
Build Tools: bootstrap.bat, b2 engine
Python Version: 3.7
b2 Command: b2 --build-dir=build/x64 address-model=64 threading=multi --build-type=complete --stagedir=./stage/x64 -j 12
// Conversion.hpp
#include <boost/python.hpp>        // import produces C2039
#include <boost/python/numpy.hpp>  // import produces C2039
#include <boost/tuple/tuple.hpp>
#include <boost/shared_ptr.hpp>
// Conversion.cpp
#include "Conversion.hpp" // importing the header file produces the compiler error

I am compiling the project with the following specs.

Compiler: MSVC cl.exe
C++ Standard: ISO C++17
Platform Toolset: Visual Studio 2022 (v143)

The compilation generates the following error.

C2039: '_copysign' is not a member of 'std' 
File: boost_1_76_python37\boost\core\cmath.hpp

I looked at python.hppand numpy.hpp and could only find a reference to std::cmath inside boost\python\detail\wrap_python.py, which is used over boost::core::cmath. I checked the std::cmath header and copysign is neither declared nor defined. How do I make sure that my Boost library uses the copysign in boost::core::cmath?

Lastique commented 1 year ago

Looks like copysign is defined as a macro somewhere, possibly in the Python headers. If that's the case, Python should be fixed, IMHO.

Lastique commented 1 year ago

It might also be useful to add a workaround to Boost.Python. CC @stefanseefeld.

pdimov commented 1 year ago

Check whether your pyconfig.h file contains #define copysign _copysign. I can't find such a line in my Python 3.9 installation, only a comment in pymath.h about it, but it might have been present in 3.7.

zerovirus123 commented 1 year ago

@pdimov Hi Peter, I checked pyconfig.h and the directive is present in Python37.

pdimov commented 1 year ago

The easiest fix then is to upgrade to a more recent Python version, one that no longer has the #define. I'm not sure what we can do on the Boost side to defend against that.

zerovirus123 commented 1 year ago

@pdimov Python310 has the #define HAVE_COPYSIGN 1 directive. Does that mean that copysign is still defined in the later Python versions.

If I build my Boost library with Python310, then the compiler would not produce the _copysign namespace error.

pdimov commented 1 year ago

#define HAVE_COPYSIGN 1 in pyconfig.h just means that the compiler has a copysign function, which Python can use without needing to redefine copysign to _copysign.