GNOME Bugzilla – Bug 759315
"check" collides with definitions in AssertMacros.h unless compiled with __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
Last modified: 2015-12-15 22:04:33 UTC
Apple defines an macro named "check" which causes ./sigc++/functors/macros/functor_trait.h.m4 fail to compile: echo "#include <AssertMacros.h> #include <sigc++/functors/functor_trait.h> " > out.cpp && clang++ -Wall -std=c++11 -c out.cpp `pkg-config sigc++-2.0 --cflags` In file included from out.cpp:3: /usr/local/Cellar/libsigc++/2.6.2/include/sigc++-2.0/sigc++/functors/functor_trait.h:87:3: warning: declaration does not declare anything [-Wmissing-declarations] static biggerthanint check(...); ^~~~~~~~~~~~~~~~~~~~ /usr/local/Cellar/libsigc++/2.6.2/include/sigc++-2.0/sigc++/functors/functor_trait.h:92:36: error: too many arguments provided to function-like macro invocation static int check(X_functor* obj, decltype(&X_functor::operator()) p = nullptr); ^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/AssertMacros.h:1291:10: note: macro 'check' defined here #define check(assertion) __Check(assertion) ^ In file included from out.cpp:3: /usr/local/Cellar/libsigc++/2.6.2/include/sigc++-2.0/sigc++/functors/functor_trait.h:92:14: warning: variable templates are a C++14 extension [-Wc++14-extensions] static int check(X_functor* obj, decltype(&X_functor::operator()) p = nullptr); ^ /usr/local/Cellar/libsigc++/2.6.2/include/sigc++-2.0/sigc++/functors/functor_trait.h:97:53: error: expected expression = sizeof(check(static_cast<T_functor*>(nullptr))) == sizeof(int) ^ 2 warnings and 2 errors generated. Apple already noticed this problem and provided a "solution": /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/AssertMacros.h * For time immemorial, Mac OS X has defined version of most of these macros without the __ prefix, which * could collide with similarly named functions or macros in user code, including new functionality in * Boost and the C++ standard library. * * A future release of Mac OS X will no longer do this, and will require that clients move to the * new macros as defined above. However, in the interim both the new and old macros will work, unless * clients define a macro __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES before this file is included * in their compilations. Clients who do not want the older macros defined can accomplish this by adding * #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 * at the top of their sources, or my adding -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 to the * gcc compilation options. maybe it would be a good idea set __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 by default on OS X via sigc++-2.0.pc cxxflags?
glibmm has several functions named check(), some of them at least 12 years old. (https://git.gnome.org/browse/glibmm/tree/glib/glibmm/main.cc) I suppose that some people use glibmm on Mac OS. I wonder how this problem is handled in glibmm. Obviously not by an extra macro definition in the .pc file. Well, unless the .pc file is modified by Apple or other distributors. Is this really a libsigc++ bug? Neither libsigc++ nor glibmm include AssertMacros.h. Who includes AssertMacros.h? Do you include it yourself before you include libsigc++ files? Does an application program do that?
I'm also not sure if this is a libsigc++ bug. On the other hand the macro definition would not hurt and save clients from trouble. The program which im trying to compile is ardour, they use both libsigc++ and AssertMacros.h. See https://github.com/Ardour/ardour/blob/d17b73e989b5825cb3caeab7321f3663adb6839d/libs/appleutility/CoreAudio105/CABufferList.h for example. For sure, I can report this problem there also.
Ardour's CAbufferList.h actually uses the check() macro. If __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES is set to 0, check() will not be defined as a preprocessor macro, and class CABufferList will not work as intended, will it? Probably it won't compile. If we should do something in libsigc++, a better solution is to rename libsigc++'s check() method. It's a private method in a template class. As far as I can see, it's not part of the ABI of libsigc++, glibmm or gtkmm. When I commented bug 755545, I learned that Ardour uses glibmm and gtkmm. I wonder why the check() methods in glibmm don't cause problems. Perhaps because most of them are old, and the Ardour code has taken them into account. Now there is also a new check() method in glibmm 2.46, in Glib::RefPtr, similar to the one in libsigc++. Perhaps it will cause problems, if you try to build Ardour with a new version of glibmm.
check() methods in don't cause problems because Ardour just undef's them where necessary: e.g. https://github.com/Ardour/ardour/blob/master/libs/ardour/globals.cc#L65 there are a few other places like this.
If renaming is possible, that would be a surprisingly easy way to solve that problem. Im building against gtkmm 2.46.2, I don't know why it does'- have the same issue. Robin, maybe you are right, but they are building against libsigc++ 2.2.10 afaik and Im talking about 2.6.2 here, so the undefs are most likely targeted to 2.2.10 specific issues.
I have renamed check(). Now it's called checksize(). Hope that's not the name of a macro anywhere. https://git.gnome.org/browse/libsigc++2/commit/?id=9bd7f99838f1fb0f67fe5a66155dc13d075041df
I tested with 2.6.2+your patch and worked very well. Thank you!