Building a testdir of module 'assert-h' with CC="gcc" CXX="g++ -std=gnu++11"
on CentOS 7, I get a compilation error:

g++ -std=gnu++11 -DHAVE_CONFIG_H -I. -I..  -DGNULIB_STRICT_CHECKING=1 
-DIN_GNULIB_TESTS=1 -I. -I. -I.. -I./.. -I../gllib -I./../gllib   -Wno-error -g 
-O2 -MT test-assert-h-c++.o -MD -MP -MF .deps/test-assert-h-c++.Tpo -c -o 
test-assert-h-c++.o test-assert-h-c++.cc
In file included from ../config.h:716:0,
                 from test-assert-h-c++.cc:20:
/usr/include/c++/4.8.2/type_traits:934:7: error: storage class specified for 
‘_gl_static_assert_function2’
       static_assert(sizeof...(_Args) > 1,
       ^
make[4]: *** [test-assert-h-c++.o] Error 1

The situation with this compiler ("g++ -std=gnu++11") is:
  - It supports 2-args static_assert in version >= 4.7,
  - It supports 1-arg static_assert in version >= 6,
  - It never supports _Static_assert.

Thus the fix (for the versions >= 4.7, < 6) is to redefine
'static_assert', but like via _GL_VERIFY (which cannot appear
inside struct {...} or class {...}), but via a macro that
dispatches on the number of arguments. Similar to what we did
for MSVC 14, just with the difference that here we can assume
an ISO C compatible preprocessor.

For completeness, I tested also "clang++ -std=gnu++11"). Here,
there is no problem: It supports 2-args static_assert and
1-arg static_assert at least in versions >= 4. It emits a warning

  warning: static_assert with no message is a C++1z extension 
[-Wc++1z-extensions]

in the 1-arg case, which (AFAIU) is correct.


2024-05-30  Bruno Haible  <br...@clisp.org>

        assert-h, verify: Fix compilation error with g++ (4.8.5) -std=gnu++11.
        Reported by Harmen <har...@stoppels.ch> at
        <https://savannah.gnu.org/bugs/index.php?65811>.
        * lib/verify.h (static_assert): In C++ mode with g++ < 6 and
        -std=gnu++11, define in a way that supports also the 1-argument
        invocations and the invocations inside C++ struct and class.

diff --git a/lib/verify.h b/lib/verify.h
index 08268c2498..978926a491 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -259,11 +259,22 @@ template <int w>
       && (!defined __cplusplus \
           || (__cpp_static_assert < 201411 \
               && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910)))
-#  if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__
+#  if (defined __cplusplus && defined __GNUG__ && __GNUG__ < 6 \
+       && __cplusplus == 201103L && !defined __clang__)
+/* g++ >= 4.7, < 6 with option -std=c++11 or -std=gnu++11 supports the
+   two-arguments static_assert but not the one-argument static_assert, and
+   it does not support _Static_assert.
+   We have to play preprocessor tricks to distinguish the two cases.  */
+#   define _GL_SA1(a1) static_assert ((a1), "static assertion failed")
+#   define _GL_SA2 static_assert
+#   define _GL_SA3 static_assert
+#   define _GL_SA_PICK(x1,x2,x3,x4,...) x4
+#   define static_assert(...) _GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1) 
(__VA_ARGS__)
+#  elif 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.
    We have to play preprocessor tricks to distinguish the two cases.
-   Since the MSVC preprocessor is not ISO C compliant (see above),.
+   Since the MSVC preprocessor is not ISO C compliant (see above),
    the solution is specific to MSVC.  */
 #   define _GL_EXPAND(x) x
 #   define _GL_SA1(a1) static_assert ((a1), "static assertion failed")




Reply via email to