One of those snippets you just copy-paste from SO? Can I please explain to you a few basics before your copy-paste this one? Let’s suppose you have developed for C++17.
Pre 2020, ISO C++ committee WG21 document N4835 was C++20 draft. Please look it up.
201703L is in there to indicate C++20 value is not declared and defined yet. That 201703L, is a standard C++17 value. Each and every compiler vendor declares 201703L for C++17 for __cplusplus
. (Or if ready yet for the C++20 code.)
These macros are for:
- situations when customers **might** try your app in systems or situations, which are undeclared as your app operating requirements.
- you have your app operating requirements documented, yes?
- the situation, when your code needs to know, is it in the C++20 or C++23 mode, now and in the future
- Etc.
One could indeed simplify and fix the exact C++ version
Let us assume you are developing for C++17. And you do not want your team or teams to accidentally overlap into the C++20 teritory.
Instead of a page long compiler agnostic and OS agnostic “wall of macros” that decides which actual C++ version is in use, one can get hold of only the C++17 value. This is all we might need: To know if are we below the required C++ 17 value or are we above the required mark.
This is the way to demand exactly C++17 and nothing else. And that will work “forever”.
1 2 3 4 5 6 7 8 9 10 11 |
#ifndef __cplusplus #error YOUR_APP requires C++ compiler #endif #if ( __cplusplus < 201703L ) #error YOUR_APP requires the standard C++17 compiler #endif #if ( __cplusplus > 201703L ) #error YOUR_APP is not ready yet for the standard C++20 (or higher) #endif |
That would indeed cover the operational requirements of the C++17 language requirement.
cl.exe has to be the odd one out
Alas, that does not work right now for developers using Microsoft cl.exe (c++ compiler). So I had to change it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#ifndef __cplusplus #error MY APP requires C++ compiler #endif #ifndef MY_CPLUSPLUS #if defined(_MSVC_LANG) && !defined(__clang__) #define MY_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG) #else #define MY_CPLUSPLUS __cplusplus #endif #endif #if (MY_CPLUSPLUS < 201703L) #error MY APP requires the standard C++17 compiler #endif #if (MY_CPLUSPLUS > 201703L) #error MY APP is not ready yet for the standard C++20 (or higher) #endif |
This is because, for me here __cplusplus == 199711L
, and my compiler is
1 2 |
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x86 Copyright (C) Microsoft Corporation. All rights reserved. |
Which was the very latest, at the moment of this writing.
To operate in a standard way, using CL you need to compile with the /Zc:__cplusplus switch to see the C++ standard defined value of the __cplusplus macro.
And nobody does that.
And what do we do now when C++20 is official?
At that moment __cplusplus
will be having the official value which we will use. Very likely our app operational requirement will then become C++17 or C++20. Ir just C++20.
The __cplusplus
value for C++20 is 202002L
1 2 3 |
#if __cplusplus >= 202002L // C++20 (and later) code #endif |
NOTE: As of this writing no vendor has 100% full C++20 implemented. Please be aware of that and use feature checking as explained here.
And yes, that would be a proverbial exercise for the reader.