compilers/c++: Add MSVC option to make the __cplusplus define accurate

Otherwise it always returns the value for c++98, starting with MSVC 2017
15.7 or later. Earlier versions are not affected by this mis-feature.

See: https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-160

This was originally applied as 0b97d58548
but later reverted because it made the CI red. Try it again, now.

Original-patch-by: Dylan Baker <dylan@pnwbakers.com>
Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
pull/10368/head
Eli Schwartz 3 years ago committed by Xavier Claessens
parent 3ae36dee42
commit 04c728a126
  1. 15
      docs/markdown/snippets/msvc_cplusplus_define.md
  2. 10
      mesonbuild/compilers/cpp.py
  3. 7
      test cases/windows/18 msvc cplusplus define/main.cpp
  4. 14
      test cases/windows/18 msvc cplusplus define/meson.build
  5. 2
      test cases/windows/3 cpp/meson.build

@ -0,0 +1,15 @@
## MSVC now sets the __cplusplus #define accurately
MSVC will always return `199711L` for `__cplusplus`, even when a newer c++
standard is explicitly requested, unless you pass a specific option to the
compiler for MSVC 2017 15.7 and newer. Older versions are unaffected by this.
Microsoft's stated rationale is that "a lot of existing code appears to depend
on the value of this macro matching 199711L", therefore for compatibility with
such (MSVC-only) code they will require opting in to the standards-conformant
value.
Meson now always sets the option if it is available, as it is unlikely that
users want the default behavior, and *impossible* to use the default behavior
in cross-platform code (which frequently breaks as soon as the first person
tries to compile using MSVC).

@ -734,6 +734,16 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
del args[i]
return args
def get_always_args(self) -> T.List[str]:
args = super().get_always_args()
# By default, MSVC has a broken __cplusplus define that pretends to be c++98:
# https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=msvc-160
# Pass the flag to enable a truthful define, if possible.
if version_compare(self.version, '>= 15.7') and '/Zc:__cplusplus' not in args:
return args + ['/Zc:__cplusplus']
return args
class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, ClangClCompiler, CPPCompiler):
id = 'clang-cl'

@ -0,0 +1,7 @@
int main() {
#if __cplusplus == 199711L
return 1;
#else
return 0;
#endif
}

@ -0,0 +1,14 @@
project('msvc __cplusplus', 'cpp', default_options : ['cpp_std=c++14'])
cpp = meson.get_compiler('cpp')
if cpp.get_id() != 'msvc'
error('MESON_SKIP_TEST: test is only relevant for msvc')
elif meson.project_version().version_compare('< 15.7')
error('MESON_SKIP_TEST: test is only relevant for msvc versions >= 15.7')
endif
test(
'main',
executable('main', 'main.cpp'),
)

@ -1,4 +1,4 @@
project('wincpp', 'cpp')
project('wincpp', 'cpp', default_options : ['cpp_std=c++14'])
exe = executable('prog', 'prog.cpp')
test('wincpp', exe)

Loading…
Cancel
Save