How Are the _Cplusplus Directive Defined in Various Compilers

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 an extern "C" block, but they're all about linkage.

Also, you probably want two #ifdef __cpluspluss:

#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.156

156) 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



Leave a reply



Submit