Opened 11 years ago
Closed 9 years ago
#6219 closed Bugs (fixed)
Apple macros break compile of has_binary_operator
Reported by: | Owned by: | Vladimir Prus | |
---|---|---|---|
Milestone: | To Be Determined | Component: | type_traits |
Version: | Boost 1.48.0 | Severity: | Problem |
Keywords: | Cc: | j.gee@… |
Description
Short version: the Apple defined macro for check() breaks the compile of some files in Boost 1.48.
Long version
I upgraded from Boost 1.44 to 1.48 and my compile broke. A little digging determined it is a conflict with the check() macro defined in AssertMacros.h which currently makes its way into many compiles. This problem has come up before, see https://svn.boost.org/trac/boost/ticket/2115.
I am compiling on Mac OS X Lion v10.7.2 with Apple LLVM compiler 3.0. This code is enough to show the problem:
#include <Carbon/Carbon.h> #include "boost/type_traits.hpp"
or more directly #include <AssertMacros.h> #include "boost/type_traits.hpp"
The first errors happen in this code in has_binary_operator.hpp where check is used.
template < typename Lhs, typename Rhs > struct operator_exists { static ::boost::type_traits::yes_type check(has_operator); // this version is preferred when operator exists static ::boost::type_traits::no_type check(no_operator); // this version is used otherwise BOOST_STATIC_CONSTANT(bool, value = (sizeof(check(((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()),make<has_operator>())))==sizeof(::boost::type_traits::yes_type))); };
Of some interest, Apple is aware of the problems being caused by the too-ordinary macro names and this text appears in the AssertMacros.h header:
* Prior to Mac OS X 10.6 the macro names used in this file conflicted with some * user code, including libraries in boost and the proposed C++ standards efforts, * and there was no way for a client of this header to resolve this conflict. Because * of this, most of the macros have been changed so that they are prefixed with * __ and contain at least one capital letter, which should alleviate the current * and future conflicts. However, to allow current sources to continue to compile, * compatibility macros are defined at the end with the old names. A tops script * at the end of this file will convert all of the old macro names used in a directory * to the new names. Clients are recommended to migrate over to these new macros as * they update their sources because a future release of Mac OS X will remove the * old macro definitions ( without the double-underscore prefix ). Clients who * want to compile without the old macro definitions can define the macro * __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES to 0 before this file is * included.
(So there is a work-around in client code.)
Change History (11)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Cc: | added |
---|
follow-up: 5 comment:3 by , 11 years ago
This definition
__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0
should definitely go into the darwin tool config.
comment:4 by , 11 years ago
Component: | None → Building Boost |
---|---|
Owner: | set to |
Should probably also go into the clang-darwin toolset as well.
Changing to "building boost", and assigning to Vladmir. If he's not the right person, I'm sure he'll chime in.
comment:5 by , 11 years ago
Component: | Building Boost → Regression Testing |
---|
Replying to marshall:
This definition
__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0
should definitely go into the darwin tool config.
Perhaps.. But that doesn't actually solve the problem. For users that do not use BB it would still break. As would also anyone compiling with an older OSX,or iOS, SDK. So we need to identify where the problems in the code are an file individual bugs. And as a preliminary step we should add this macro to the inspection report, if it's not already there. And because of that I'm shifting this to the testing side.
comment:6 by , 10 years ago
Component: | Regression Testing → type_traits |
---|
comment:7 by , 9 years ago
Just ran into this with boost 1.55. This could be fixed without ever touching ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES. Just change the static variable names in operator_exists ( type_traits/detail/has_binary_operator.hpp ) from "check" to something else.
comment:8 by , 9 years ago
Sadly, there is lots more than just this.
- boost/container/detail/function_detector.hpp has a template member named "check"
- Boost.Concept has structures named both "check" and "require"
- Boost.Geometry has several uses of "check"
and the file <AssertMacros.h>
defines many more macros than just those two.
comment:9 by , 9 years ago
The perfect is the enemy of the good?
Fixing has_binary_operator.hpp fixes a lot of real use cases (lexical_cast for one) by just changing some internal identifiers. Even if you don't fix every use case, you make some use cases better, without making any use cases worse.
comment:10 by , 9 years ago
This took me almost two hours to sort out yesterday. Perhaps the addition of something like...
#if defined(__MACH__) && defined(__APPLE__) && defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) && __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES #warning You will need to define ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES to 0 before the inclusion of Cocoa headers (perhaps in your prefix header) #end if
...might help lower the impedance here. Or something to that effect. While it may be non-trivial to work around this vendor annoyance, mankind does possess the technology to at least shorten the path to the workaround.
comment:11 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
This is fixed in current develop (or at least type_traits is, can't comment on other libraries).
(I regret not previewing the report, mea culpa for the cosmetic grinkles.)