Re: Why do we test a build using g++?
[email protected] (Sam James) Tue, 30 Jun 2026 00:52:00 +0100
| Newsgroups | perl.perl5.porters |
|---|---|
| Organization | Gentoo |
| Message-ID | <[email protected]> |
--=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable "Kurt Starsinic" <[email protected]> writes: > (Note: I have not reviewed gcc's source code for many years. Most of what= I have to say about gcc was certainly mostly true at one point, but might = not be today.) > > IIRC, the main reason for testing with g++ is because it's capable of > finding errors that gcc can't detect (they are, after all, independent > compiler implementations). No, they're just distinct frontends, and those frontends have different rules because they're different languages. > g++ is also able to perform *significant* > additional optimizations. As far as I'm aware, of a close observer and sometime contributor of GCC, this is not true anymore. > > That being said, we can always turn off warnings we're not interested in,= e.g., -Wno-missing-field-initializers. > > I realize I haven't popped my head up here in quite a while. Not looking = to start a beef, just provide some context. :) > > - Kurt > > On Mon, Jun 29, 2026, at 17:41, Paul "LeoNerd" Evans wrote: >> TL;DR: We have some CI test builds that use -Dcc=3D'g++', to test if we = can >> build perl using g++ as the "C" compiler. I wonder - why do we do this? >> Perl is written in C, not C++, which is a different language. Can we >> please not? >> >> >> I ask because it's increasingly annoying and getting in the way. Before >> we added C99 (and thus were only using C89 features), this wasn't so >> bad, but we introduced C99 specifically so we could use some features >> that were introduced only 25 years ago, instead of having to stick to >> features that are over 35 years old. >> >> One feature of C99 that I intend to use a lot is the ability to >> initialise structures with named initialisers, and to be able to omit >> fields to imply the compiler-assigned defaults of zero for integers or >> NULL for pointers. This makes it nicely convenient to initialise >> structures that, for example, have optional "flags" or other features >> in them, or pointers that are rarely used, and so most of the time you >> leave them as NULL. Not having to write lots of extra lines in the >> source makes the code clearer. >> >> The default C99-and-not-C++ compiler is perfectly happy for me to write >> code such as: >> >> static const struct MagicFunctions magicfuncs_customop_xop =3D { >> .ver =3D 2, >> .shape =3D MGv2s_BASE, >> .debug_name =3D "customop_xop", >> .free_mg =3D &customop_xop_free, >> }; >> >> This is relatively easy on the human eye, because it draws attention to >> only those fields that we're putting something interesting in, without >> a lot of extra clutter. It's almost as nice as having named parameters >> with optional defaults in them. ;) >> >> But g++ doesn't like this; it complains: >> >> op.c:16427:1: warning: missing initializer for member >> =E2=80=98MagicFunctions::_v1_vtbl=E2=80=99 [-Wmissing-field-initia= lizers] >> 16427 | }; >> | ^ >> op.c:16427:1: warning: missing initializer for member >> =E2=80=98MagicFunctions::flags=E2=80=99 [-Wmissing-field-initializ= ers] >> op.c:16427:1: warning: missing initializer for member >> =E2=80=98MagicFunctions::user_size=E2=80=99 [-Wmissing-field-initi= alizers] >> op.c:16427:1: warning: missing initializer for member >> =E2=80=98MagicFunctions::clone_mg=E2=80=99 [-Wmissing-field-initia= lizers] >> >> In order to appease it, I tried just adding a bunch of zero/NULL/{} >> fields at the end of the struct; but then it complains: >> >> op.c:16432:1: error: designator order for field =E2=80=98MagicFunction= s::flags=E2=80=99 >> does not match declaration order in =E2=80=98const MagicFunctions= =E2=80=99 >> >> It also still gets upset that initialisers that I have in fact written >> aren't there, because it doesn't see them. Or something. I don't know, >> I'm not a C++ programmer. I write in C. >> >> It seems the only way to make it happy is to write a lot more noisy >> structure, that's far worse on the human reader: >> >> static const struct MagicFunctions magicfuncs_customop_xop =3D { >> ._v1_vtbl =3D {}, >> .ver =3D 2, >> .shape =3D MGv2s_BASE, >> .flags =3D 0, >> .debug_name =3D "customop_xop", >> .user_size =3D 0, >> .free_mg =3D &customop_xop_free, >> .clone_mg =3D NULL, >> }; >> >> I find this quite a bit worse to look at, because of all those empty >> junk lines being added. It makes it harder to see what's "interesting" >> about this struct, as even the zeroes and the NULLs are in there. Plus >> that leading ._v1_vtbl is even worse. It's present in the structure >> definition itself in order to make a compatible hole with (version 1) >> MAGIC structure, but shouldn't really be thought about or visible as >> part of the v2 API. So having to add it in *every* struct >> initialisation is very annoying indeed. >> >> Aside from being more cluttered and less clear to look at to the human >> reader, I also find this worse for longterm maintainability. A key >> selling point of C99's ability to imply zeroes/etc.. for fields you >> don't name, is that if you later extend the struct definition by adding >> more fields to it, you don't have to go around all your initialisers >> everywhere to add more ".foo =3D 0" lines. You can just ignore them, >> knowing they will default to zeroes if you don't need them. It makes it >> easier and nicer to extend those data types later without breaking >> existing source code. Plus, an actual C99 compiler doesn't care if the >> named initialisers don't appear in the same order as the fields in the >> struct. The whole point of naming them is that now order doesn't >> matter. You can reorder the elements in the struct without upsetting >> users of that struct, even in initialisers. Yes you'll still have to >> recompile it - but that's fine for all the code within the source tree. >> You just don't have to manually edit all your .c files. >> >> >> I think therefore I have made a reasonable case for wanting to be able >> to use this C99 named initialiser syntax. So now I want to understand >> why we care if we can compile perl source using g++. >> >> I understand that historically we have used this as a test to see that >> perl's *headers* are suitable for use by both a C compiler and a C++ >> compiler, for those folks who want to write XS extensions in C++. That >> made sense when we were only using C89, and the C++ compilers were >> basically able to handle a superset of that anyway. But C99 and C++ >> diverge a little, so that is no longer really true. >> >> I'm not aware of any direct reason why the source of the perl binary >> itself needs to be compilable by a C++ compiler; especially not since >> it gets in the way of us writing the code we want to write - in C99. >> >> I'd like to propose that (if there isn't another valid reason that is >> stronger than our desire to use C99 features) we find another way to >> test if the perl headers are compatible with C++. For example, could we >> ship a tiny "helloworld.cpp" program that also pulls in <perl.h> and >> <XSUB.h> or somesuch? Or maybe we write a tiny XS extension in C++ and >> compiled with g++, to use for such testing purposes? >> >> Or failing all of those; would we be able to test with g++ in some sort >> of mode where we can ask it to accept things that C99 considers valid. >> I don't know if this one is possible - see above under "I'm not a C++ >> programmer", but I can't imagine we're the first and only people to >> ever run into this issue. Perhaps there's some way we can get around it? >> >> --=20 >> Paul "LeoNerd" Evans >> >> [email protected] >> http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQEBBAEWCgCpFiEEJaa7iN2bdkxrVUHCc4QJ9SDfkZAFAmpDBSEbFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25z Lm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQyNUE2QkI4OEREOUI3NjRDNkI1NTQx QzI3Mzg0MDlGNTIwREY5MTkwDxxzYW1AZ2VudG9vLm9yZwAKCRBzhAn1IN+RkE1z AP97cGNSa5wJqzvrztbjSE2+vSA6dIx9bW3OO2NMl6oN9QD9EIpA5E+tEutInuOF gv1Lc9UfjDgAtmh8nEwZBvt2Yg0= =t/xk -----END PGP SIGNATURE----- --=-=-=--