2012-02-15

What about C++11 in Xcode?

This started out as a very small problem: I am using C++, Objective C++ and Objective C mixed in one project. This usually works pretty well. However, when including MapKit, the compiler choked on an Objective C++ file. It seems the MapKit.h header wants to use isinf(). This function has been introduced with ISO C 99, but it it is not included in ISO C++ 98. Hence the failure of Xcode's gcc and clang compilers.

To work around this problem I was thinking of trying to set the project settings to use ISO C++ 11, or C++ 0x, since Xcode's compilers are not that up to date. This is pretty easy:


And I guess this would work for most people. However, I am also using boost in this project. And I guess it is rather up to date, concerning the new language specification. However this also means that there is a problem with clang's support of the language. I get a ton of errors in boost when switching to C++ 0x in clang:


In short, I think the C++ 11 support is not quite there yet with Xcode 4.2 and clang 3.0. I will try to post updates when future Xcode releases are coming out. If, alternatively, someone has hints on how to compile boost with clang 3.0, I am also glad to try that out.

Update: There is a fork on gitorious of the boost on iPhone build script, which already uses the clang compiler. I hacked the script even more to use --std=c++0x as a flag and it builds fine. Now I will try to link this new framework to an iOS project compiled with clang using C++ 0x.

Update 2: I found the root of the problem. The fantastic people over at #boost on freenode helped me figuring it out. In short: boost::fusion defines nil, which is an Objective C keyword. Thus we get lots of problems. Objective C defines nil and Nil in objc/objc.h. A minimal program that compiles successfully:

#include <boost/phoenix/core/reference.hpp>
#import <CoreFoundation/CoreFoundation.h>

int main()
{
    return 1;
}
Using this command line:
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ \
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk \
-framework Foundation -Fpath/to/boost/framework --std=c++0x -arch armv7 \
-stdlib=libc++ -mthumb -miphoneos-version-min=5.0 foo.mm -o foo 
If you swap the to include / import statements, the program will not compile, since now the ObjC nil makes boost break. There is a boost ticket tracking this issue, with a proposed patch attached, which renames the boost nil to nil_.

Update 3: The patch works fine, but now I get internal compiler errors from clang. The compile triggers a segmentation violation at some point during the compilation of my project. I guess clang 3.0 is still a bit experimental. I submitted a bug report and will revert to using the default settings of Xcode for the time being.

No comments:

Post a Comment