0

I'm developing with Visual Studio 2019, and would like to be able to compile my C++ program conditionally based on the language standard chosen (C++20, C++17, etc.) from Project Properties -> General Properties -> C++ Language Standard. What gets defined when I set it C++20, for example, so that I can use it as:

#ifdef WHAT_DO_I_PUT_HERE_FOR_C++_20 
#else
#ifdef WHAT_DO_I_PUT_HERE_FOR_C++_17
...
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Vectorizer
  • 1,076
  • 9
  • 24

2 Answers2

2

You could use the MSVC predefined macro _MSVC_LANG:

#ifndef VT_CPP_VERSION
# if defined (_MSVC_LANG)
#  define VT_CPP_VERSION _MSVC_LANG
# else
#  define VT_CPP_VERSION __cplusplus
# endif
#endif

#if defined (VT_CPP_VERSION)
# if   (VT_CPP_VERSION >= 202002L)
  // 20 or above
# elif (VT_CPP_VERSION >= 201703L)
  // 17
# elif (VT_CPP_VERSION >= 201402L)
  // 14
# elif (VT_CPP_VERSION >= 201103L)
  // 11
# else
  // cry.
# endif
#endif

If you need to get this value after the code has already been compiled (for example: a shared library), then you can use a function.

[[maybe_unused]] long version_used() noexcept {
#if defined (_MSVC_LANG)
  return _MSVC_LANG;
#else
  return __cplusplus;
#endif
}
viraltaco_
  • 814
  • 5
  • 14
1

This should work:

#if (__cplusplus >= 202002L)
    // C++20 (or later) code
#elif (__cplusplus == 201703L) 
    // C++17 code
#else
    // C++14 or older code
#endif
jpo38
  • 20,821
  • 10
  • 70
  • 151
  • Unfortunately it does not work with Visual Studio 2019 Version 16.10.4 Thanks for your input – Vectorizer Dec 10 '21 at 22:27
  • @Vectorizer That would then be a compliancy defect of Visual Studio, and a whooping big one at that. – DevSolar Dec 11 '21 at 16:28
  • @DevSolar: Maybe I am missing something. All I am doing is setting the C++ language standard to C++17 and expecting the relevant portion of the code to be active. – Vectorizer Dec 11 '21 at 16:53
  • @Vectorizer: Understood. Testing `__cplusplus` as shown here is a mechanism that is defined by the language standard, so every standard-compliant compiler should allow it. Unfortunately Microsoft thinks standards are for other people only. If it does not work as shown, that would be a fault in Microsoft's compiler, making it non-compliant in a pretty important way. Working around the issue by using some of Microsoft's non-standard extensions (as shown by ViralTaco_'s answer) makes your code less portable / readable, the *real* solution would be MS getting their act together. – DevSolar Dec 11 '21 at 17:23
  • @DevSolar Understood. I am afraid I don't have the means to influence Microsoft to get its act together. By the way, the problem is still here in the latest version: 16.11.7 – Vectorizer Dec 11 '21 at 17:29
  • @Vectorizer: What value does `__cplusplus` evaluate to in that version? – DevSolar Dec 11 '21 at 17:38
  • @DevSolar: Always to 199711 (for C++14, 17, 20) – Vectorizer Dec 11 '21 at 17:59
  • 2
    @Vectorizer: [Set /Zc to enable updated __cplusplus macro.](https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-170). Sorry, didn't know about that myself. – DevSolar Dec 11 '21 at 18:04
  • 1
    @DevSolar: Thank you for your help on this while I was offline ;-)! – jpo38 Dec 11 '21 at 20:23