> Something that's not entirely clear to me yet is what's the benefit of
> having clang compile software against gcc's libstdc++ vs. gcc6
> compiling it.

I have attempted to build both Qt and Octave with gcc6, and I have run across a 
few unpleasant incompatibilities.

Example:
    #include <stdio.h>
    const int N = 5;
    const int j = N;
    int main()
    {
         printf("%d\n",j);
    }

Clang recognizes the above code as valid C, while GCC does not.
Apparently, the C standard allows a little bit of leeway here.
See
    
http://stackoverflow.com/questions/21592494/initializer-element-is-not-constant-error-for-no-reason-in-linux-gcc-compilin
    
http://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w
At least one system header file (and perhaps others), 
/System/Library/Frameworks/CoreGraphics.framework/Headers/CGFont.h,
relies on the clang’s interpretation of the standard.


Example:
    #include <Carbon/Carbon.h>
    int main() {}
On recent versions of macOS, GCC can not compile the above code.
I know that Carbon has been deprecated for some time, but it is a convenient 
example.

/usr/include/AvailabilityInternal.h gets pulled into source code any number of 
ways.
This can lead to problems since GCC compilers do not understand Clang's 
__attribute__.
/usr/include/Availability.h protects against this with preprocessor commands
#if defined(__has_feature)
#elif __has_feature(attribute_availability)
#if __has_feature(attribute_availability_with_message)
/usr/include/AvailabilityInternal.h does not always use these safeguards, which 
means GCC sometimes cannot compile code which has nothing to do with 
Availability.h.

I filed a bug report with Apple (r29805005), but I have not heard back.

After trying to work around these problems for a time, I gave up.

> And what's the relation of all this to the magic
> -D_GLIBCXX_USE_CXX11_ABI=0 flag.
My point of reference: 
https://gcc.gnu.org/onlinedocs/libstdc%2B%2B/manual/using_dual_abi.html
The following code is what I wrote to test various combinations.
The -D_GLIBCXX_USE_CXX11_ABI=0 forces the new libstdc++ string and list 
implementations to be compatible with the old libstdc++ string and list 
implementations.

main.cxx:
    #include "f1.hxx"
    int main() { f1("Hi There"); }

f1.hxx:
    #include <string>
    void f1(const std::string& string);

f1.cxx
    #include "f1.hxx"
    #include <iostream>
    void f1(const std::string& string) { std::cout << string << "\n"; }

/opt/local/bin/g++-mp-6 -c -D_GLIBCXX_USE_CXX11_ABI=0 f1.cxx
/usr/bin/clang++ -c -stdlib=libstdc++ -std=c++11 main.cxx
/usr/bin/clang++ -stdlib=libstdc++ *.o
./a.out
/opt/local/bin/g++-mp-6 *.o
./a.out

> 
>> I should have made clear that a major downside of choice #2 is that it 
>> requires a library dependency on gcc6.
> 
> Thanks, I missed that. And I agree that this is a bit of a downside.
> What kind of dependency is that exactly? Is it only a dependency
> because the port needs to make sure that gcc's libstdc++ is present at
> the time of compilation or are there some other more hardwired
> constraints?
When the patched clang is called, the header files of gcc6 are used and the 
libraries from libgcc are linked in.
After compilation, the libraries from libgcc have to be there for the resulting 
binary to run.

> And we should finally address binary builds for libc++. That would
> likely solve 99.9% of our C++11-related problems.

Unfortunately, I do not even know where to begin to solve this problem.

-Marcus

Reply via email to