When building a testdir with C++ tests on MSVC 14, I see this error: source='../../gltests/test-stddef-c++2.cc' object='test-stddef-c++2.obj' libtool=no \ DEPDIR=.deps depmode=msvc7 /bin/sh ../../build-aux/depcomp \ /home/bruno/msvc/compile cl -nologo -DHAVE_CONFIG_H -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_WINXP -I/usr/local/msvc64/include -MD -c -o test-stddef-c++2.obj `cygpath -w '../../gltests/test-stddef-c++2.cc'` test-stddef-c++2.cc C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstddef(27): error C2874: using-declaration causes a multiple declaration of 'std::rpl_max_align_t' C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstddef(24): note: see declaration of 'std::rpl_max_align_t' make[4]: *** [Makefile:9886: test-stddef-c++2.obj] Error 2
So, rpl_max_align_t is apparently making trouble. But the max_align_t override is not needed on this platform, in C++ mode, since the original max_align_t already has alignment 8. 2019-12-11 Bruno Haible <[email protected]> stddef: Fix compilation error in C++ mode on MSVC. * lib/stddef.in.h (max_align_t): With MSVC in C++ mode, don't define it; instead, include <cstddef>. diff --git a/lib/stddef.in.h b/lib/stddef.in.h index e01f41b..e6c601a 100644 --- a/lib/stddef.in.h +++ b/lib/stddef.in.h @@ -83,20 +83,26 @@ /* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is a hack in case the configure-time test was done with g++ even though - we are currently compiling with gcc. */ -#if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) -# if !GNULIB_defined_max_align_t + we are currently compiling with gcc. + On MSVC, max_align_t is defined only in C++ mode, after <cstddef> was + included. Its definition is good since it has an alignment of 8 (on x86 + and x86_64). */ +#if defined _MSC_VER && defined __cplusplus +# include <cstddef> +#else +# if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) +# if !GNULIB_defined_max_align_t /* On the x86, the maximum storage alignment of double, long, etc. is 4, but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, and the C11 standard allows this. Work around this problem by using __alignof__ (which returns 8 for double) rather than _Alignof (which returns 4), and align each union member accordingly. */ -# ifdef __GNUC__ -# define _GL_STDDEF_ALIGNAS(type) \ - __attribute__ ((__aligned__ (__alignof__ (type)))) -# else -# define _GL_STDDEF_ALIGNAS(type) /* */ -# endif +# ifdef __GNUC__ +# define _GL_STDDEF_ALIGNAS(type) \ + __attribute__ ((__aligned__ (__alignof__ (type)))) +# else +# define _GL_STDDEF_ALIGNAS(type) /* */ +# endif typedef union { char *__p _GL_STDDEF_ALIGNAS (char *); @@ -104,8 +110,9 @@ typedef union long double __ld _GL_STDDEF_ALIGNAS (long double); long int __i _GL_STDDEF_ALIGNAS (long int); } rpl_max_align_t; -# define max_align_t rpl_max_align_t -# define GNULIB_defined_max_align_t 1 +# define max_align_t rpl_max_align_t +# define GNULIB_defined_max_align_t 1 +# endif # endif #endif
