Re: Make copyObject work in C++ - Mailing list pgsql-hackers
| From | Jelte Fennema-Nio |
|---|---|
| Subject | Re: Make copyObject work in C++ |
| Date | |
| Msg-id | DFXV193BOBQ8.1BY2PK8YRJ9O1@jeltef.nl Whole thread Raw |
| In response to | Re: Make copyObject work in C++ (Andres Freund <andres@anarazel.de>) |
| Responses |
Re: Make copyObject work in C++
Re: Make copyObject work in C++ |
| List | pgsql-hackers |
On Sun Jan 25, 2026 at 5:50 PM CET, Andres Freund wrote:
> I'm pretty sceptical this is the right direction.
The only other option I can think of is not supporting C++ extension on
MSVC unless they are compiled with C++20 (or later). I don't
particularly care about Windows C++ extensions myself, so I personally
would be fine with that choice. It seems a bit harsh, though.
> We were going for designated
> initializers for a reason, namely that we expect more arguments to be added
> over time and perhaps eventually also to remove some. And this will just lead
> to that being harder because we have to worry about C++ extensions.
Adding new arguments (aka fields) should cause no problems. Assuming
we'd add them at the end of the Pg_magic_struct definition. Removing
ones seems like even for C you'd need different PG_MODULE_MAGIC_EXT
invocations depending on PG_VERSION_NUM. I don't see how using
positional args would make that harder.
> But I'm also confused as to why it's needed - there's nomixing of designated
> and non-designated initializers that I can see? If you use
> PG_MODULE_MAGIC_EXT(.name = "whatnot"), it evaluates down to
>
> extern __attribute__((visibility("default"))) const Pg_magic_struct *Pg_magic_func(void); const Pg_magic_struct *
Pg_magic_func(void){ static const Pg_magic_struct Pg_magic_data = { .len = sizeof(Pg_magic_struct), .abi_fields = {
190000/ 100, 100, 32, 64, true, "PostgreSQL", }, .name="whatnot"}; return &Pg_magic_data; } extern int
no_such_variable;
>
> And indeed, contra to what you reported upthread, I can't get clang to report
> a warning about that. I do obviously see warnings about the wrong order if I
> pass the arguments in the wrong order, but that's a lot less problematic. And
> omitted args don't trigger warnings, as you noted.
It sounds like I wasn't clear enough what the problem was. The main
problem currently is that MSVC C++ fails to compile a cpp file
containing PG_MODULE_MAGIC (or PG_MODULE_MAGIC_EXT) unless you use /std:c++20.
Afaict it would have been possible to do so before 9324c8c580 (aka
anything before PG18), but since that commit you need /std:c++20. The
fact that we haven't heard anyone complain so far, might be an indication
that not many people (or maybe anyone) is using C++ extensions on Windows.
The only way to make PG_MODULE_MAGIC work on MSVC pre-C++20 is to
partially revert 9324c8c580, and use positional arguments in the
definition of PG_MODULE_MAGIC_DATA again. Like I've done in v7-0001.
For C extensions v7-0001 has no downsides. However, after applying
v7-0001, C++ extensions that use PG_MODULE_MAGIC_EXT with designated
parameters will get the following warning on at least clang 18 on my
machine:
meson setup --prefix ~/.pgenv/pgsql-master --debug build --reconfigure -Dc_args='-fno-omit-frame-pointer'
-Dcassert=true
meson test -C build --suite setup --suite test_cplusplusext
[2202/2268] Compiling C++ object src/test/modules/test_cplusplusext/test_cplusplusext.so.p/test_cplusplusext.cpp.o
../src/test/modules/test_cplusplusext/test_cplusplusext.cpp:23:21: warning: mixture of designated and non-designated
initializersin the same initializer list is a C99 extension [-Wc99-designator]
23 | PG_MODULE_MAGIC_EXT(.name="test_cplusplusext",.version= "1.2");
| ^~~~~~~~~~~~~~~~~~~~~~~~~
../src/include/fmgr.h:548:24: note: expanded from macro 'PG_MODULE_MAGIC_EXT'
548 | PG_MODULE_MAGIC_DATA(__VA_ARGS__); \
| ^~~~~~~~~~~
../src/include/fmgr.h:509:2: note: expanded from macro 'PG_MODULE_MAGIC_DATA'
509 | __VA_ARGS__ \
| ^~~~~~~~~~~
../src/test/modules/test_cplusplusext/test_cplusplusext.cpp:23:1: note: first non-designated initializer is here
23 | PG_MODULE_MAGIC_EXT(.name="test_cplusplusext",.version= "1.2");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/include/fmgr.h:548:3: note: expanded from macro 'PG_MODULE_MAGIC_EXT'
548 | PG_MODULE_MAGIC_DATA(__VA_ARGS__); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/include/fmgr.h:507:2: note: expanded from macro 'PG_MODULE_MAGIC_DATA'
507 | sizeof(Pg_magic_struct), \
| ^~~~~~~~~~~~~~~~~~~~~~~
Note that you need to use meson test, not meson install, otherwise
test_cplusplusext.cpp won't get compiled.
So to be clear, yes right now there's no mixing of designated and
non-designated initializers. But after applying v7-0001 there would be
when you use something like this:
PG_MODULE_MAGIC_EXT(.name="test_cplusplusext",.version= "1.2");
And while the C standard allows mixing designated and non-designated
initializerss, the C++ standard (even C++20) does not.
pgsql-hackers by date: