gcc compiles C programs as C, and C++ programs as C++, thus requiring an 'extern "C"' declaration in C++. Whereas, g++ compiles C programs as C++, and C++ programs as C++, thus requiring that the 'extern "C"' declaration must NOT be used in C++.
Checking standard flags without any input, both
g++ -E -dM - </dev/null
gcc -E -dM - </dev/null
give the same results.
__GNUG__ is equivalent to testing (__GNUC__ && __cplusplus)
which again will not differentiate gcc from g++ inside a C++ source listing.
What is the magic for
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
to wrap around the extern "C"{ declarations? Thanks.
Edit: I realize this is a rather esoteric case. The test needs to be done on the compiler flavor, not on the source code flavor. In both cases the test is being performed inside a C++ source code listing (which is why I mentioned GNUG is inadequate). To clarify, for test main.cpp:
#include <iostream>
int
main( int argc, char **argv )
{
#ifdef __cplusplus <<<< FIX THIS ONE
std::cout << "I was compiled using g++" << std::endl;
#else
std::cout << "I was compiled using gcc" << std::endl;
#endif
}
when compiled with either
g++ main.cpp
or
gcc main.cpp -lstdc++
in both cases, it seems to incorrectly give as output "I was compiled using g++". So it would seem that cplusplus is not the correct flag to use in this case. Am I wrong? Or what is the correct flag?
Edit 2: Thanks, guys. Here is one example for you. Large legacy system "Alpha" is written mostly in C, with a little C++, and uses large legacy source package "Charlie", written in C++. It uses the g++ system to compile and link, and demands that Charlie's headers have no extern "C" definitions in them, or else it refuses to link. Large legacy system "Bravo" is written mostly in C, with a little C++, and also uses the same legacy source package Charlie, written in C++. It uses the gcc system to compile and link, and demands that Charlie's headers must have extern "C" definitions in them, or else it refuses to link. New systems "Delta", "Echo", and "Foxtrot" would also like to reuse parts of source from Charlie, compiler to be used is uncertain. The correct answer is to hack Charlie's headers, once and for all, with
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
extern "C" {
#endif
...
declarations of code
...
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
}
#endif
and then be done with it. Otherwise there will always be linking problems. Yes, of course it could be possible to compile two sets of libraries in this particular case, one under C and one under the C++ convention, and then mandate that thou shalt use this particular library for this particular flavor of linking. Or I could come up with two sets of headers. Either of those is inelegant and will continue to cause problems down the road, in this example; there are other cases. As to the comment that both g++ and gcc are using the same compiler under the hood, and so it can't possibly matter, sadly, it does. The package as a whole refuses to link when the wrong 'extern "C"' dogma is/isn't included. Yes, there are other ways of attacking the general problem, but it's a simple question. Either such a flag exists, or it is known not to exist, or the answer is not known definitively. I don't know, myself.