What version (or hash if on master) of pybind11 are you using?
b07fddb21993d4fa358822dcbf2b36e0fd20db46
Problem description
Just tracked down a really cryptic bug. Pybind11's PYBIND11_DEBUG_MARKER hack (where it does #undef _DEBUG temporarily, and then defines it back) causes errors in TBB headers.
Here's what happens:
You set _DEBUG to 1 somehow.
Then you include any TBB header. They all include tbb/detail/_config.h that defines macro TBB_USE_DEBUG according to the value of _DEBUG:
If _DEBUG is undefined, #define TBB_USE_DEBUG 0
If _DEBUG is defined to nothing, #define TBB_USE_DEBUG 1
Otherwise (_DEBUG == 0 or 1), #define TBB_USE_DEBUG _DEBUG <- this branch is chosen
Then you #include <pybind11/pybind11.h>. That temporarily #undefines _DEBUG, and then defines it back, but the original value is lost, as it always defines it to empty, regardless of the original value.
Then you include some other TBB header that does #if TBB_USE_DEBUG. Now TBB_USE_DEBUG expands to empty, and #if with no expression is a compilation error:
......./oneapi/tbb/concurrent_vector.h:893:22: error: expected value in expression
893 | #if TBB_USE_DEBUG
In other words, TBB by itself can handle any value of _DEBUG: both empty and 0/1. What it can't handle is the value suddenly changing from 1 to empty.
Proposed solution:
Improve the PYBIND11_DEBUG_MARKER hack to correctly reproduce the original value of the macro.
Required prerequisites
What version (or hash if on master) of pybind11 are you using?
b07fddb21993d4fa358822dcbf2b36e0fd20db46
Problem description
Just tracked down a really cryptic bug. Pybind11's
PYBIND11_DEBUG_MARKER
hack (where it does#undef _DEBUG
temporarily, and then defines it back) causes errors in TBB headers.Here's what happens:
You set
_DEBUG
to1
somehow.Then you include any TBB header. They all include
tbb/detail/_config.h
that defines macroTBB_USE_DEBUG
according to the value of_DEBUG
:_DEBUG
is undefined,#define TBB_USE_DEBUG 0
_DEBUG
is defined to nothing,#define TBB_USE_DEBUG 1
_DEBUG
==0
or1
),#define TBB_USE_DEBUG _DEBUG
<- this branch is chosenThen you
#include <pybind11/pybind11.h>
. That temporarily#undef
ines_DEBUG
, and then defines it back, but the original value is lost, as it always defines it to empty, regardless of the original value.Then you include some other TBB header that does
#if TBB_USE_DEBUG
. NowTBB_USE_DEBUG
expands to empty, and#if
with no expression is a compilation error:In other words, TBB by itself can handle any value of
_DEBUG
: both empty and0
/1
. What it can't handle is the value suddenly changing from1
to empty.Proposed solution:
Improve the
PYBIND11_DEBUG_MARKER
hack to correctly reproduce the original value of the macro.Here's how you store the value:
And this is how you load it back:
The macro emptiness check is grabbed straight from TBB.
Reproducible example code
Compile with MSVC (or Clang-cl), and ensure
_DEBUG
is defined to1
.Is this a regression? Put the last known working version here if it is.
Not a regression