With MSVC 14.30 (market name "Visual Studio 2022" [1]), I see compilation
errors in C++ mode:

/home/bruno/msvc/compile cl -nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" 
-DEXEEXT=\".exe\" -I. -I../../gltests -I..  -DGNULIB_STRICT_CHECKING=1 
-DIN_GNULIB_TESTS=1 -I. -I../../gltests -I.. -I../../gltests/.. -I../gllib 
-I../../gltests/../gllib -D_WIN32_WINNT=_WIN32_WINNT_WIN7 
-I/usr/local/msvc64/include  -MD -c -o test-assert-h-c++.obj `cygpath -w 
'../../gltests/test-assert-h-c++.cc'`
test-assert-h-c++.cc
C:\Program Files\Microsoft Visual 
Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\iterator(248): error 
C2059: syntax error: 'string'
...

The cause is that the C++ library code has static_assert invocations with
arguments that contain commas (template instantiations), and these only
work if static_assert is a compiler built-in, not a macro. So, Gnulib
must not define static_assert as a macro on this platform. Fortunately
the need for this macro definition is gone, as MSVC 14.30's static_assert
supports both the 2-arguments form as well as the newer 1-argument form. [2]

[1] https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
[2] https://learn.microsoft.com/en-us/cpp/cpp/static-assert?view=msvc-170

This patch thus fixes it.


2023-04-20  Bruno Haible  <br...@clisp.org>

        assert-h, verify: Fix compilation error in C++ mode with MSVC 14.30.
        * lib/verify.h (_Static_assert): In C++ mode with MSVC 14.1 or newer,
        define merely to static_assert.
        (static_assert): In C++ mode with MSVC 14.1 or newer, don't define.

diff --git a/lib/verify.h b/lib/verify.h
index c700243209..e4af91517e 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -241,10 +241,16 @@ template <int w>
 #   define _Static_assert(...) \
       _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
 #  else
-    /* Work around MSVC preprocessor incompatibility with ISO C; see
-       <https://stackoverflow.com/questions/5134523/>.  */
-#   define _Static_assert(R, ...) \
-      _GL_VERIFY ((R), "static assertion failed", -)
+#   if defined __cplusplus && _MSC_VER >= 1910
+     /* In MSVC 14.1 or newer, static_assert accepts one or two arguments,
+        but _Static_assert is not defined.  */
+#    define _Static_assert static_assert
+#   else
+     /* Work around MSVC preprocessor incompatibility with ISO C; see
+        <https://stackoverflow.com/questions/5134523/>.  */
+#    define _Static_assert(R, ...) \
+       _GL_VERIFY ((R), "static assertion failed", -)
+#   endif
 #  endif
 # endif
 /* Define static_assert if needed.  */
@@ -252,7 +258,7 @@ template <int w>
       && __STDC_VERSION__ < 202311 \
       && (!defined __cplusplus \
           || (__cpp_static_assert < 201411 \
-              && __GNUG__ < 6 && __clang_major__ < 6)))
+              && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910)))
 #  if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__
 /* MSVC 14 in C++ mode supports the two-arguments static_assert but not
    the one-argument static_assert, and it does not support _Static_assert.




Reply via email to