Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building Perl 5.40.1 in C++ mode with Visual Studio 2019 fails #23152

Open
etna opened this issue Mar 23, 2025 · 7 comments
Open

Building Perl 5.40.1 in C++ mode with Visual Studio 2019 fails #23152

etna opened this issue Mar 23, 2025 · 7 comments

Comments

@etna
Copy link

etna commented Mar 23, 2025

As per title. When win32\Makefile is edited to enable the USE_CPLUSCPLUS= define option, the build fails instantly. Build environment is Windows 11 with VS 2019 Community.

Build output is as follow:

D:\Sources\perl-5.40.1\perl-5.40.1\win32>nmake

Microsoft (R) Program Maintenance Utility Version 14.16.27054.0
Copyright (C) Microsoft Corporation.  All rights reserved.

        if not exist ".\mini" mkdir ".\mini"
        copy config_H.vc .\mini\config.h
        1 file(s) copied.
        cl -c -Imini -nologo -GF -W3 -MD -TP -EHsc -std:c++20 -I.\include -I. -I.. -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -D_CRT_SECURE_NO_DEPRECATE  -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNINGS -DPERLDLL -DPERL_CORE   -O1 -Zi -GL -fp:precise -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -Fo.\mini\av.obj ..\av.c
cl : Command line warning D9002 : ignoring unknown option '-std:c++20'
av.c
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1169): warning C4804: '<=': unsafe use of type 'bool' in operation
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1164): warning C4018: '<=': signed/unsigned mismatch
..\av.c(288): warning C4244: 'argument': conversion from '__int64' to 'I32', possible loss of data
..\av.c(359): warning C4244: 'argument': conversion from '__int64' to 'I32', possible loss of data
..\av.c(436): warning C4244: 'argument': conversion from '__int64' to 'const I32', possible loss of data
..\av.c(884): warning C4244: 'argument': conversion from '__int64' to 'U32', possible loss of data
..\av.c(1174): warning C4244: 'argument': conversion from '__int64' to 'I32', possible loss of data
        cl -c -Imini -nologo -GF -W3 -MD -TP -EHsc -std:c++20 -I.\include -I. -I.. -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -D_CRT_SECURE_NO_DEPRECATE  -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNINGS -DPERLDLL -DPERL_CORE   -O1 -Zi -GL -fp:precise -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -Fo.\mini\caretx.obj ..\caretx.c
cl : Command line warning D9002 : ignoring unknown option '-std:c++20'
caretx.c
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1169): warning C4804: '<=': unsafe use of type 'bool' in operation
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1164): warning C4018: '<=': signed/unsigned mismatch
        cl -c -Imini -nologo -GF -W3 -MD -TP -EHsc -std:c++20 -I.\include -I. -I.. -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -D_CRT_SECURE_NO_DEPRECATE  -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNINGS -DPERLDLL -DPERL_CORE   -O1 -Zi -GL -fp:precise -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -Fo.\mini\class.obj ..\class.c
cl : Command line warning D9002 : ignoring unknown option '-std:c++20'
class.c
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1169): warning C4804: '<=': unsafe use of type 'bool' in operation
d:\sources\perl-5.40.1\perl-5.40.1\inline.h(1164): warning C4018: '<=': signed/unsigned mismatch
..\class.c(199): warning C4267: 'initializing': conversion from 'size_t' to 'U32', possible loss of data
..\class.c(289): warning C4244: 'initializing': conversion from 'UV' to 'U32', possible loss of data
..\class.c(290): warning C4244: 'initializing': conversion from 'UV' to 'U32', possible loss of data
..\class.c(297): warning C4244: 'initializing': conversion from 'UV' to 'U32', possible loss of data
..\class.c(421): warning C4804: '-': unsafe use of type 'bool' in operation
..\class.c(428): warning C4804: '-': unsafe use of type 'bool' in operation
..\class.c(446): warning C4804: '-': unsafe use of type 'bool' in operation
..\class.c(580): error C2059: syntax error: '.'
..\class.c(583): error C2143: syntax error: missing ';' before '}'
..\class.c(583): error C2059: syntax error: '}'
..\class.c(584): error C2143: syntax error: missing ';' before '{'
..\class.c(584): error C2447: '{': missing function header (old-style formal list?)
..\class.c(585): error C2059: syntax error: '}'
..\class.c(585): error C2143: syntax error: missing ';' before '}'
..\class.c(667): warning C4244: 'initializing': conversion from 'PADOFFSET' to 'U32', possible loss of data
..\class.c(880): warning C4244: 'initializing': conversion from 'PADOFFSET' to 'U32', possible loss of data
..\class.c(1057): error C2059: syntax error: '.'
..\class.c(1060): error C2143: syntax error: missing ';' before '}'
..\class.c(1060): error C2059: syntax error: '}'
..\class.c(1061): error C2143: syntax error: missing ';' before '{'
..\class.c(1061): error C2447: '{': missing function header (old-style formal list?)
..\class.c(1064): error C2059: syntax error: ','
..\class.c(1065): error C2143: syntax error: missing ';' before '{'
..\class.c(1065): error C2447: '{': missing function header (old-style formal list?)
..\class.c(1066): error C2059: syntax error: '}'
..\class.c(1066): error C2143: syntax error: missing ';' before '}'
NMAKE : fatal error U1077: 'D:\VisualStudio2019\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64\cl.EXE' : return code '0x2'
Stop.

Any advice on how this can be resolved will be greatly appreciated.
By the way, a 'normal' build with USE_CPLUSCPLUS commented out succeeds.

@mauke
Copy link
Contributor

mauke commented Mar 23, 2025

All untested, but you can try the following:

  • upgrade to a newer version of Visual Studio (possibly Visual Studio 2019 version 16.11 or newer?), or
  • edit win32\Makefile and change -std:c++20 to -std:c++latest.

@bulk88
Copy link
Contributor

bulk88 commented Mar 23, 2025

perl5/class.c

Line 582 in f722f11

.apply = &apply_class_attribute_isa,

static void
apply_class_attribute_isa(pTHX_ HV *stash, SV *value)
{
    assert(HvSTASH_IS_CLASS(stash));
    struct xpvhv_aux *aux = HvAUX(stash);
static struct {
    const char *name;
    bool requires_value;
    void (*apply)(pTHX_ HV *stash, SV *value);
} const class_attributes[] = {
    { .name           = "isa",
      .requires_value = true,
      .apply          = &apply_class_attribute_isa,
    },
    { NULL, false, NULL }
};

What is & of a C function mean? I'm not talking about & of a 4 or 8 bytes long C function pointer variable.

& of a C function looks to me like trying to memcpy() a C function and send it through TCPIP, or trying to launch a new /bin/g++ (linker) process. Perl core/most CPAN XS can never use the C++ ref feature.

apply_class_attribute_isa no () is an rval that generates a fn ptr. AFAIK &apply_class_attribute_isa, is almost the same as writing *(void**)&memcpy = S_instrument_memcpy; which means (no asm lang) executing the /bin/g++ or /bin/ld process.

So &apply_class_attribute_isa is either CC compile error, or something 1337 C code doing Assembly lang/PE/ELF/PLT/GOT header/ring 0 OS kernel tricks.

If &apply_class_attribute_isa is a GUID/unique non colliding marker for == cmp then apply_class_attribute_isa is good enough. If &apply_class_attribute_isa is supposed to be a randomly runtime changing func ptr, a new my_perl var and a new typedef apply_class_attribute_isa_T; is needed.

Similar example

"Error: file not found\n" = "Error: archivo no encontrado"\n;

Worked in February 1970. It was probably a syntax error by January 1980. That feature can still be turned on in MSVC 2022 with a certain flag nobody ever uses. Historic perl core/Configure universally disables that feature if it discovers a random closed src Unix CC has it turn on by default.

@mauke
Copy link
Contributor

mauke commented Mar 23, 2025

What is & of a C function mean?

& is the address-of operator in C. It returns the memory address of (= a pointer to) an lvalue or function.

HTH

@bulk88
Copy link
Contributor

bulk88 commented Mar 23, 2025

& is the address-of operator in C. It returns the memory address of (= a pointer to) an lvalue or function.

Why write void *vp = (void*)&memcpy; when 99% of ppl write void *vp = (void*)memcpy;?

If its valid PDF C, why try to write unit tests for the end user's C compiler at particular SHA1 of disk file /usr/bin/cc? Only metaconfig/Configure.sh is supposed to do that, not class.c.

@tonycoz
Copy link
Contributor

tonycoz commented Mar 23, 2025

apply_class_attribute_isa no () is an rval that generates a fn ptr. AFAIK &apply_class_attribute_isa, is almost the same as writing *(void**)&memcpy = S_instrument_memcpy; which means (no asm lang) executing the /bin/g++ or /bin/ld process.

So &apply_class_attribute_isa is either CC compile error, or something 1337 C code doing Assembly lang/PE/ELF/PLT/GOT header/ring 0 OS kernel tricks.

&function_name is a pointer to function_name, though the & is unnecessary, since function names are automatically converted to pointers to function (C11, 6.3.2.1p4). It's not any kind of special syntax.

As to the original problem: building with a C++ compiler isn't intended for general use, only as a way to get the supposed better error reporting from C++ compilers (which you mostly only get by writing C++ code).

But we also want to use some C99, features, so you need a compiler that supports designated member initialisation, which is a C++ 20 feature.

We specifically avoid designated array initialisation since no C++ standard supports it (though g++ does support it as an extension.)

We don't use these features in headers unless the code using that feature is guarded to prevent it being compiled outside of core use.

Do you have some special need to build perl as C++?

@etna
Copy link
Author

etna commented Mar 24, 2025

All untested, but you can try the following:

  • upgrade to a newer version of Visual Studio (possibly Visual Studio 2019 version 16.11 or newer?), or
  • edit win32\Makefile and change -std:c++20 to -std:c++latest.

Solved it. Solution is a (somewhat) combination of both. I was calling vcvarsall.bat with the oldest VC toolkit supported by VS2019, which 14.16. Apparently, 14.16 cannot handle the code and both options -std:c++20 or -std:c++latest

Starting vcvarsall.bat with 14.21 instead (which is also very old) resulted in all the errors disappearing except for one re: -std:c++20 where Visual Studio explicitly pointed out in the error that -std:c++latest used be used instead.

With both the 14.21 VC toolkit and -std:c++latest perl compiled successfully in C++ mode.

Should I close this issue?

@etna
Copy link
Author

etna commented Mar 24, 2025

As to the original problem: building with a C++ compiler isn't intended for general use, only as a way to get the supposed better error reporting from C++ compilers (which you mostly only get by writing C++ code).

Do you have some special need to build perl as C++?

Not really. The option was there, and a couple of years back I successfully built perl with this option enabled, so I just thought it was a supported build option and build mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants