How are the __cplusplus directive defined in various compilers?
The 199711L stands for Year=1997, Month = 11 (i.e., November of 1997) -- the date when the committee approved the standard that the rest of the ISO approved in early 1998.
For the 2003 standard, there were few enough changes that the committee (apparently) decided to leave that value unchanged.
For the 2011 standard, it's required to be defined as 201103L, (again, year=2011, month = 03) again meaning that the committee approved the standard as finalized in March of 2011.
For the 2014 standard, it's required to be defined as 201402L, interpreted the same way as above (February 2014).
For the 2017 standard, it's required to be defined as 201703L (March 2017).
For the 2020 standard, the value has been updated to 202002L (February 2020).
Before the original standard was approved, quite a few compilers normally defined it to 0
(or just an empty definition like #define __cplusplus
) to signify "not-conforming". When asked for their strictest conformance, many defined it to 1
.
I almost forgot to mention, but one more tidbit about ancient compilers: a few of the earliest versions of cfront (and probably a few others copying it) defined c_plusplus
instead of __cplusplus
. I don't recall it's being defined to any meaningful value though.
__cplusplus compiler directive defined and not defined
Look here: Combining C++ and C — how does #ifdef __cplusplus
work?
extern "C"
doesn't really change the way that the compiler reads the
code. If your code is in a .c file, it will be compiled as C, if it is
in a .cpp file, it will be compiled as C++ (unless you do something
strange to your configuration).What
extern "C"
does is affect linkage. C++ functions, when compiled,
have their names mangled -- this is what makes overloading possible.
The function name gets modified based on the types and number of
parameters, so that two functions with the same name will have
different symbol names.Code inside an
extern "C"
is still C++ code. There are limitations on
what you can do in anextern "C"
block, but they're all about linkage.
Also, you probably want two #ifdef __cplusplus
s:
#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
}
#endif
Otherwise, your C code will never see your definitions.
How to define a directive as an other directive in C?
There's no way to create your own preprocessor directives. The #define
directive allows you to define new source symbols only.
What you're currently doing is the proper way to handle differing directives on different compilers.
What is the value of __cplusplus for C++17?
tl;dr: For C++17, __cplusplus
is 201703L
.
What is the value of
__cplusplus
when using C++17?
According to the draft standard N4594 §16.8/p1 Predefined macro names [cpp.predefined] (Emphasis Mine):
The following macro names shall be defined by the implementation:
__cplusplus
The name__cplusplus
is defined to the value
201402L when compiling a C++ translation unit.156156) It is intended that future versions of this standard will
replace the value of this macro with a greater value. Non-conforming
compilers should use a value with at most five decimal digits.
However the same value is appointed for the C++14 standard. Apparently it seems so, that there's no official/standard __cplusplus
value set yet for the C++17 standard.
In GCC versions 6.1 and 7.0 the value is changed to 201500
Live Demo
In Clang version 3.8 and 3.9 the value is unchanged 201406.
Consequently, you'll have to wait a little bit for the standard value to come out.
--- Update ---
According to the C++ standard §19.8/p1 Predefined macro names [cpp.predefined] (Emphasis Mine):
1 The following macro names shall be defined by the
implementation:
__cplusplus
The integer literal 201703L.
Thus, the value of __cplusplus
when using C++17 shall be 201703L.
How do I check for C++20 support? What is the value of __cplusplus for C++20?
It's too early for that.
Until the standard replaces it, use:
#if __cplusplus > 201703L
// C++20 code
#endif
since the predefined macro of C++20 is going to be larger than the one of C++17.
As @SombreroChicken's answer mentions, [cpp.predefined] (1.1) specifies (emphasis mine):
__cplusplus
The integer literal
201703L
. [Note: It is intended that future versions of this International Standard will replace the value
of this macro with a greater value.]
The macros used, as of Nov 2018, are:
- GCC 9.0.0:
201709L
for C++2a. Live demo - Clang 8.0.0:
201707L
. Live demo - VC++ 15.9.3:
201704L
(as @Acorn's answer mentions).
PS: If you are interested in specific features, then [cpp.predefined] (1.8) defines corresponding macros, which you could use. Notice though, that they might change in the future.
When you define a value in C how does the compiler select the data type
The compiler does no such thing. The preprocessor substitues 100000
for CountCycle
.
Once that substitution has been completed, the compiler can take over. 100000
has the type int
if it can fit in that range, a long
if it can't.
See a C++ Reference and a C Reference.
How to control #define directive in different projects ...?
You can't. Each C++ source file is compiled independently, and settings in one cannot affect another. You'll have to do this on project level.
One way to do that would be to set up different project (and solution) configurations for different values of this macro. Instead of just the usual Debug
and Release
, you could add Debug-Display
, Debug-Return
etc. You can then define the macros in the project settings for each configuration. This will make sure you link the correctly built version of your library.
As a side note, you're using illegal names in your code. A name which contains double underscores, or starts with an underscore followed by an uppercase letter, is reserved for the compiler & standard library. User code is not allowed to use such names for its own purposes.
Working of the compiler directive in C++
Macros are not the same thing as variables.
Your compiler will translate the program
#include <iostream>
#define test 50
int main()
{
cout << test;
return 0;
}
to
#include <iostream>
int main()
{
cout << 50;
return 0;
}
by replacing the name test
by its value given at your #define
statement. You might want to take a look at some tutorials you can find on the internet e.g.:
#define getmax(a,b) ((a)>(b)?(a):(b))
This would replace any occurrence of getmax followed by two arguments
by the replacement expression, but also replacing each argument by its
identifier, exactly as you would expect if it was a function:// function macro
#include <iostream>
using namespace std;
#define getmax(a,b) ((a)>(b)?(a):(b))
int main()
{
int x=5, y;
y= getmax(x,2);
cout << y << endl;
cout << getmax(7,x) << endl;
return 0;
}
Related Topics
Linux C++: How to Profile Time Wasted Due to Cache Misses
How to Pass Derived Classes by Reference to a Function Taking Base Class as a Parameter
How Are the _Cplusplus Directive Defined in Various Compilers
Do I Have to Use Atomic<Bool> for "Exit" Bool Variable
Deciphering C++ Template Error Messages
Static Polymorphism Definition and Implementation
How to Compress Slot Calls When Using Queued Connection in Qt
Gui Toolkits, Which Should I Use
Pointers to Virtual Member Functions. How Does It Work
Implicit VS Explicit Conversion
Problems Using Member Function as Custom Deleter with Std::Shared_Ptr
Simpler Way to Create a C++ Memorystream from (Char*, Size_T), Without Copying the Data
What Is a Nested Name Specifier
Comma Operator in If Condition