Hi, I'm upgrading a project that used a 8-month-old copy of gnulib to today's version, and testing the result with various compilers.
This is a C++17 project that is not internationalized and that uses the following modules: argmatch argp closeout error isatty mkstemp mkstemps progname secure_getenv stpcpy strverscmp sys_wait My copy of gnulib is also patched with a patch I sent in 2013: https://lists.gnu.org/archive/html/bug-gnulib/2013-12/msg00106.html I compile with -Werror. Testing the result with clang++ 11.0.1-2 (Debian unstable), I observe the following two issues: (1) lib/argmatch.h includes lib/gettext.h which fails as follows > clang++ -DHAVE_CONFIG_H -I. -I.. -I.. -I.. -I../buddy/src -I../lib -I../lib > -W -Wall -Werror -Wint-to-void-pointer-cast -Wzero-as-null-pointer-constant > -Wcast-align -Wpointer-arith -Wwrite-strings -Wcast-qual -DXTSTRINGDEFINES > -Wdocumentation -Wmissing-declarations -Woverloaded-virtual > -Wmisleading-indentation -Wimplicit-fallthrough -Wnull-dereference > -Wsuggest-override -Wpedantic -fvisibility=hidden -fvisibility-inlines-hidden > -DSPOT_BUILD -std=c++17 -g -O -MT autcross.o -MD -MP -MF .deps/autcross.Tpo > -c -o autcross.o autcross.cc > In file included from autcross.cc:34: > In file included from ../lib/argmatch.h:31: > ../lib/gettext.h:234:22: error: zero as null pointer constant > [-Werror,-Wzero-as-null-pointer-constant] > if (msg_ctxt_id != NULL) > ^~~~ > nullptr > /usr/lib/llvm-11/lib/clang/11.0.1/include/stddef.h:84:18: note: expanded from > macro 'NULL' > # define NULL __null > ^ > In file included from autcross.cc:34: > In file included from ../lib/argmatch.h:31: > ../lib/gettext.h:282:22: error: zero as null pointer constant > [-Werror,-Wzero-as-null-pointer-constant] > if (msg_ctxt_id != NULL) > ^~~~ > nullptr > /usr/lib/llvm-11/lib/clang/11.0.1/include/stddef.h:84:18: note: expanded from > macro 'NULL' > # define NULL __null > ^ > 2 errors generated. Just replacing these two tests with "if (msg_ctxt_id)" gets rid of the issue. (2) ARGMATCH_VERIFY ends up using _Static_assert which is a C11 keyword that does not exist in C++. However static_assert exists in C++11 with two args, and since C++17 with one arg. > clang++ -DHAVE_CONFIG_H -I. -I.. -I.. -I.. -I../buddy/src -I../lib -I../lib > -W -Wall -Werror -Wint-to-void-pointer-cast -Wzero-as-null-pointer-constant > -Wcast-align -Wpointer-arith -Wwrite-strings -Wcast-qual -DXTSTRINGDEFINES > -Wdocumentation -Wmissing-declarations -Woverloaded-virtual > -Wmisleading-indentation -Wimplicit-fallthrough -Wnull-dereference > -Wsuggest-override -Wpedantic -fvisibility=hidden -fvisibility-inlines-hidden > -DSPOT_BUILD -std=c++17 -g -O -MT common_aoutput.o -MD -MP -MF > .deps/common_aoutput.Tpo -c -o common_aoutput.o common_aoutput.cc > common_aoutput.cc:85:1: error: '_Static_assert' is a C11 extension > [-Werror,-Wc11-extensions] > ARGMATCH_VERIFY(check_args, check_types); > ^ > ../lib/argmatch.h:45:5: note: expanded from macro 'ARGMATCH_VERIFY' > verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1) > ^ > ../lib/verify.h:289:20: note: expanded from macro 'verify' > # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) > ^ > ../lib/verify.h:229:41: note: expanded from macro '_GL_VERIFY' > # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) > ^ > common_aoutput.cc:397:7: error: '_Static_assert' is a C11 extension > [-Werror,-Wc11-extensions] > ARGMATCH_VERIFY(args, format); > ^ > ../lib/argmatch.h:45:5: note: expanded from macro 'ARGMATCH_VERIFY' > verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1) > ^ > ../lib/verify.h:289:20: note: expanded from macro 'verify' > # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) > ^ > ../lib/verify.h:229:41: note: expanded from macro '_GL_VERIFY' > # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) > ^ > 2 errors generated. to work around this, I've just changed the definition of _GL_VERIFY in lib/verify.h from > #if defined _GL_HAVE__STATIC_ASSERT > # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) > #else > # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ > extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ > [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] > #endif to > #if defined __cpp_static_assert > # define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC) > #elif defined _GL_HAVE__STATIC_ASSERT > # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) > #else > # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ > extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ > [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] > #endif However there are a few __cplusplus tests at the top of the file that attempt to tell when _Static_assert can be used (and failed here), and I do not really follow that logic. Those macros check for __cpp_static_assert to assume something about _Static_assert, which seems dubious. -- Alexandre Duret-Lutz