This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix Mingw GCC C++ build errors PL_inf/PL_nan
authorDaniel Dragan <bulk88@hotmail.com>
Tue, 24 Apr 2018 18:12:46 +0000 (14:12 -0400)
committerSteve Hay <steve.m.hay@googlemail.com>
Thu, 24 May 2018 12:16:31 +0000 (13:16 +0100)
commita385474c9667eb0a1b5fbba5f817d90686929349
treeefecd1ad7359a3ec16fae72aa85e746ee074d2a9
parent636adee66dd861ad7cbeac765ffcabebc9daaaed
fix Mingw GCC C++ build errors PL_inf/PL_nan

Trying a USE_CPLUSPLUS=define build with dmake (USE_CPLUSPLUS not
implemented in GNUMakefile) causes the following error

---------
gcc -c -xc++ -I.\include -I. -I.. -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -fwrapv -
fno-strict-aliasing -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\globals.o  ..
\globals.c
In file included from ..\globals.c:32:0:
..\perl.h:6754:50: error: too many initializers for 'U8 [8] {aka unsigned char [
8]}'
 INFNAN_U8_NV_DECL PL_inf = { { LONGDBLINFBYTES } };
                                                  ^
..\perl.h:6790:50: error: too many initializers for 'U8 [8] {aka unsigned char [
8]}'
 INFNAN_U8_NV_DECL PL_nan = { { LONGDBLNANBYTES } };
                                                  ^
dmake:  Error code 129, while making 'mini\globals.o'
---------
in plain C mode builds, this error was just a warning and nobody paid
attention to it for a while
---------
gcc -c  -I.\include -I. -I.. -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -fwrapv -fno-s
trict-aliasing -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\globals.o  ..\glob
als.c
In file included from ..\globals.c:32:0:
..\perl.h:5432:42: warning: excess elements in array initializer
 #define INFNAN_U8_NV_DECL EXTCONST union { U8 u8[NVSIZE]; NV nv; }
                                          ^
..\perl.h:6754:1: note: in expansion of macro 'INFNAN_U8_NV_DECL'
 INFNAN_U8_NV_DECL PL_inf = { { LONGDBLINFBYTES } };
 ^
..\perl.h:5432:42: warning: (near initialization for 'PL_inf.u8')
 #define INFNAN_U8_NV_DECL EXTCONST union { U8 u8[NVSIZE]; NV nv; }
                                          ^
..\perl.h:6754:1: note: in expansion of macro 'INFNAN_U8_NV_DECL'
 INFNAN_U8_NV_DECL PL_inf = { { LONGDBLINFBYTES } };
 ^
..\perl.h:5432:42: warning: excess elements in array initializer
 #define INFNAN_U8_NV_DECL EXTCONST union { U8 u8[NVSIZE]; NV nv; }
                                          ^
-------------

Now on VC C++ build, LONGDBLINFBYTES is 8 bytes, as defined in
LONGDBLINFBYTES macro in config_H.vc, and for VC, "long double" is always
typedefed by the CC to "double", so there was no warning, but on GCC,
"long double" is the 80 bit/10 byte type and in config_H.gc the 12 byte
version of INF is inside LONGDBLINFBYTES macro. Because LONG_DOUBLESIZE
define was previously "8" because of makefile logic regardless of CC,

#  elif NVSIZE == LONG_DOUBLESIZE && defined(LONGDBLINFBYTES)
INFNAN_U8_NV_DECL PL_inf = { { LONGDBLINFBYTES } };

was being hit on GCC, even though NVSIZE is 8 as it should be, but
LONGDBLINFBYTES was 12. Hence the warning. I didnt research why this
warning on GCC didn't cause test failures. Perhaps full perl recomputes
the correct initializer in config_sh.PL and doesn't rely on what was in the
miniperl initializer for PL_inf.

To fix things, always emit the correct value for LONG_DOUBLESIZE and dont
hardcode it at 8 for miniperl. 8 must stay for all VCs, and 12/16 is for
GCC. Although GNUMakefile doesn't support a USE_CPLUSPLUS build option,
it has provisons to support it one day. To keep things in sync, copy
miniperl config.h append changes from makefile.mk to GNUMakefile. Also
collapse 2 shell cmd lines in "ifeq ($(USE_LONG_DOUBLE),define)" to reduce
number of proc launches of cmd.exe by the maketool (perf issue).

Next C++ build issue.

APItest.xs: In function 'void XS_XS__APItest__Backrefs_Comctl32Version(Perl
Interpreter*, CV*)':
APItest.xs:6806:37: error: cast from 'LPSTR {aka char*}' to 'WORD {aka shor
t unsigned int}' loses precision [-fpermissive]
                                     MAKEINTRESOURCE(VS_FILE_INFO));
                                     ^
dmake:  Error code 129, while making 'APItest.o'

VS_FILE_INFO is internally "RT_VERSION" which is MAKEINTRESOURCE(16). The
output type of MAKEINTRESOURCE is a char *. GCC complains about casting
that char * back down to a WORD (aka short). Put in a size_t used for
pointer arithimitic to silence the error. Another option is to
remove the outer MAKEINTRESOURCE in APItest.xs since RT_VERSION has
MAKEINTRESOURCE internally, but that assumes implementation details of
headers so pick the less dependency on header design option.
ext/XS-APItest/APItest.pm
ext/XS-APItest/APItest.xs
win32/GNUmakefile
win32/makefile.mk