15
  • What does the C++ macro __cplusplus contain and expand to?

  • Does the macro __cplusplus always, even in oldest C++ implementation, contain and expand to a numeric value?

  • Is it safe to use #if __cplusplus or should we use instead of that #ifdef __cplusplus?


Conclusion (added later)

From comments and accepted answer:

  • __cplusplus expands to a number representing the standard's version, except pre-standard C++ in the early 90s (which simply expanded to 1).

  • Yes, even in oldest C++ implementation (expands to a numeric value).

  • No, #ifdef should be used when header is shared with C-language (because some C-compilers will warn when #if checks undefined macro).

9
  • For C, it should be undefined (unless you're dealing with a malicious compiler writer); for C++, it should be defined, possibly to a useful value, but at least defined. If you want to work with 'even the oldest C++ implementations', do not assume anything more than "it is defined". Commented Apr 19, 2018 at 7:45
  • What do you consider to be "the oldest C++ implementation"? C++98? Older? How much older? Commented Apr 19, 2018 at 7:52
  • The question was originally tagged with C, and the title included 'C' rather than C++. The tags were predominantly C++ tags, though. However, C11 §6.10.8 Predefined macro names ¶3 says: The implementation shall not predefine the macro __cplusplus, nor shall it define it in any standard header. The C99 standard says essentially the same, in a slightly different section. The C90 standard was silent on the issue. Commented Apr 19, 2018 at 7:56
  • since an undefined macro will expand to false/zero we just need __cplusplus evaluate to "true" when defined so we can short up code and conditions Commented Apr 19, 2018 at 8:04
  • 2
    For a long time g++ defined it as 1. #ifdef is the traditional way to test, some compilers will warn if you use #if instead. Commented Apr 19, 2018 at 8:12

3 Answers 3

19

Yes, it always does expand to numeric value and its meaning is the version of C++ standard that is being used. According to cppreference page, __cplusplus macro should expand to:

  • 199711L (until C++11),
  • 201103L (C++11),
  • 201402L (C++14),
  • 201703L (C++17),
  • 202002L (C++20)
  • 202302L (C++23)

The difference between #if and #ifdef directives is that #ifdef should be used to check whether given macro has been defined to allow a section of code to be compiled.

On the other hand #if (#else, #elif) directives can be used to check whether specified condition is met (just like typical if-condition).

Sign up to request clarification or add additional context in comments.

4 Comments

are you even sure for oldest C++ version ?
Yes, the C++98 standard explicitly says so — I checked in my copy.
Note that for a long time, __cplusplus in some compilers simply expanded to 1.
Of course, if you were experimenting with pre-standard c++ in the early 90s, that standard didn't exist, just as now you can experiment with c++20. If you are still using such a compiler all bets are off, but then your sanity must be questioned. :-)
3

__cplusplus is required to be defined by the C++ standard. For C++11 or higher __cplusplus > 199711L should hold true.


Does the macro __cplusplus always, even in oldest C++ implementation, contain and expand to a numeric value?

Yes it does.


19.8 C++11

__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. — end note  ]


C++98

__cplusplus The name _ _cplusplus is defined to the value 199711L when compiling a C ++ translation unit. 143)

Comments

2

Unfortunately, the __cplusplus macro has the value 199711 in MS Visual Studio 2022, regardless of the specified C++ standard. Use _MSVC_LANG instead. See VS comment.

This seems to work:

#if defined(_MSVC_LANG)  // MS compiler has different __cplusplus value.
#   if _MSVC_LANG < 201703
#       error Please compile for C++17 or higher
#   endif
#else  // All other compilers.
#   if __cplusplus < 201703
#       error Please compile for C++17 or higher
#   endif
#endif

4 Comments

You can just use #if __cplusplus < 201703 nowadays, as your link states! The issue was resolved back in 2018. VS2019 and VS2022 have full C++17 support, but VS2017 was still a bit iffy.
No, __cplusplus has the value 199711 in MS Visual Studio 2022 with C++17.
There's also the compiler flag /Zc:__cplusplus learn.microsoft.com/en-us/cpp/build/reference/…
Expanding on user202729's comment to provide the context from that link that addresses the confusion: "The /Zc:__cplusplus compiler option enables the __cplusplus preprocessor macro to report an updated value for recent C++ language standards support. By default, Visual Studio always returns the value 199711L for the __cplusplus preprocessor macro." So, the __cplusplus macro is only reliable if the flag has been passed. Otherwise, the _MSVC_LANG macro is always reliable in MSVC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.