It is possible to write a function, which, when compiled with a C compiler will return 0, and when compiled with a C++ compiler, will return 1 (the trivial sulution with
#ifdef __cplusplus
is not interesting).
For example:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Of course, the above will work only if sizeof (char)
isn't the same as sizeof (int)
Another, more portable solution is something like this:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
I am not sure if the examples are 100% correct, but you get the idea. I believe there are other ways to write the same function too.
What differences, if any, between C++03 and C++11 can be detected at run-time? In other words, is it possible to write a similar function which would return a boolean value indicating whether it is compiled by a conforming C++03 compiler or a C++11 compiler?
bool isCpp11()
{
//???
}
From this question:
Core Language
Accessing an enumerator using
::
:You can also abuse the new keywords
Also, the fact that string literals do not anymore convert to
char*
I don't know how likely you are to have this working on a real implementation though. One that exploits
auto
The following is based on the fact that
operator int&&
is a conversion function toint&&
in C++0x, and a conversion toint
followed by logical-and in C++03That test-case doesn't work for C++0x in GCC (looks like a bug) and doesn't work in C++03 mode for clang. A clang PR has been filed.
The modified treatment of injected class names of templates in C++11:
A couple of "detect whether this is C++03 or C++0x" can be used to demonstrate breaking changes. The following is a tweaked testcase, which initially was used to demonstrate such a change, but now is used to test for C++0x or C++03.
Standard Library
Detecting the lack of
operator void*
in C++0x'std::basic_ios
I got an inspiration from What breaking changes are introduced in C++11?:
This is based on the new string literals that take precedence over macro expansion.
Unlike prior C++, C++0x allows reference types to be created from reference types if that base reference type is introduced through, for example, a template parameter:
Perfect forwarding comes at the price of breaking backwards compatibility, unfortunately.
Another test could be based on now-allowed local types as template arguments:
How about a check using the new rules for
>>
closing templates:Alternatively a quick check for
std::move
: