Make copyObject work in C++

Started by Jelte Fennema-Nio3 months ago39 messages
Jump to latest
#1Jelte Fennema-Nio
postgres@jeltef.nl

Calling copyObject fails in C++ with an error like in most setups:

error: use of undeclared identifier 'typeof'; did you mean 'typeid'

This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by using decltype instead of typeof when
including the header in C++.

Realized because of Thomas' not about how much of our headers should
work in C++, and remembering I hit this specific problem myself.

Another approach would be to force the value of HAVE_TYPEOF to 0 if __cplusplus.

Attachments:

v1-0001-Make-copyObject-work-in-C.patchapplication/x-patch; name=v1-0001-Make-copyObject-work-in-C.patchDownload+3-2
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jelte Fennema-Nio (#1)
Re: Make copyObject work in C++

Jelte Fennema-Nio <postgres@jeltef.nl> writes:

Calling copyObject fails in C++ with an error like in most setups:
error: use of undeclared identifier 'typeof'; did you mean 'typeid'
This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by using decltype instead of typeof when
including the header in C++.

Hmm, this only fixes the one use-case. Admittedly we have only one
use-case, but as soon as we have another we'll have a new problem.
How about instead modifying the macro? Maybe something like this
in c.h (untested):

#ifdef __cplusplus
#undef typeof
#define typeof decltype
#define HAVE_TYPEOF 1
#endif

Another approach would be to force the value of HAVE_TYPEOF to 0 if __cplusplus.

That would be sad, because we'd lose the type checking ability
of copyObject() in C++ code.

BTW, grepping finds a number of random references to __typeof__ and
__typeof, which probably ought to be updated to be just typeof.

regards, tom lane

#3Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#1)
Re: Make copyObject work in C++

On 05.12.25 15:46, Jelte Fennema-Nio wrote:

Calling copyObject fails in C++ with an error like in most setups:

error: use of undeclared identifier 'typeof'; did you mean 'typeid'

This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by using decltype instead of typeof when
including the header in C++.

Realized because of Thomas' not about how much of our headers should
work in C++, and remembering I hit this specific problem myself.

Another approach would be to force the value of HAVE_TYPEOF to 0 if __cplusplus.

In the long run, I would like to change copyObject() to use
typeof_unqual instead, because that handles qualifiers more correctly.
(Currently, copyObject() of a const-qualified pointer results in a
const-qualified pointer, which is nonsensical because the reason you
made the copy is that you can modify it.) See attached patch for an
example. Does C++ have something that is semantically similar to that?

Attachments:

0001-Change-copyObject-to-use-typeof_unqual.patchtext/plain; charset=UTF-8; name=0001-Change-copyObject-to-use-typeof_unqual.patchDownload+101-3
#4Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#2)
Re: Make copyObject work in C++

On 07.12.25 20:45, Tom Lane wrote:

Hmm, this only fixes the one use-case. Admittedly we have only one
use-case, but as soon as we have another we'll have a new problem.
How about instead modifying the macro? Maybe something like this
in c.h (untested):

#ifdef __cplusplus
#undef typeof
#define typeof decltype
#define HAVE_TYPEOF 1
#endif

AFAICT, both gcc and clang support typeof in C++ mode as well. So this
kind of renaming could be confusing.

#5Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Tom Lane (#2)
Re: Make copyObject work in C++

On Sun Dec 7, 2025 at 8:45 PM CET, Tom Lane wrote:

#ifdef __cplusplus
#undef typeof
#define typeof decltype
#define HAVE_TYPEOF 1
#endif

Went with defining pg_exprtype (pg_typeof already exists). Undefining
typeof seemed a bit heavy-handed. Especially since I think it would be
nice to backport this so C++ extensions can use copyObject directly.

BTW, grepping finds a number of random references to __typeof__ and
__typeof, which probably ought to be updated to be just typeof.

Added a follow on patch that starts using pg_exrtype in all those
places.

Attachments:

v2-0001-Make-copyObject-work-in-C.patchtext/x-patch; charset=utf-8; name=v2-0001-Make-copyObject-work-in-C.patchDownload+15-3
v2-0002-Use-pg_exprtype-instead-of-__typeof__-or-__typeof.patchtext/x-patch; charset=utf-8; name=v2-0002-Use-pg_exprtype-instead-of-__typeof__-or-__typeof.patchDownload+8-17
#6David Geier
geidav.pg@gmail.com
In reply to: Peter Eisentraut (#3)
Re: Make copyObject work in C++

On 08.12.2025 08:57, Peter Eisentraut wrote:

On 05.12.25 15:46, Jelte Fennema-Nio wrote:

Calling copyObject fails in C++ with an error like in most setups:

error: use of undeclared identifier 'typeof'; did you mean 'typeid'

This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by using decltype instead of typeof when
including the header in C++.

Realized because of Thomas' not about how much of our headers should
work in C++, and remembering I hit this specific problem myself.

Another approach would be to force the value of HAVE_TYPEOF to 0 if
__cplusplus.

In the long run, I would like to change copyObject() to use
typeof_unqual instead, because that handles qualifiers more correctly.
(Currently, copyObject() of a const-qualified pointer results in a
const-qualified pointer, which is nonsensical because the reason you
made the copy is that you can modify it.)  See attached patch for an
example.  Does C++ have something that is semantically similar to that?

Since C++11 there's std::remove_const which can be used as
std::remove_const<decltype(type)>::type.

I'm not aware of anything pre C++11, except for rolling your own variant
of std::remove_const via template specialization.

--
David Geier

#7Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: David Geier (#6)
Re: Make copyObject work in C++

On Mon, 8 Dec 2025 at 09:33, David Geier <geidav.pg@gmail.com> wrote:

Since C++11 there's std::remove_const which can be used as
std::remove_const<decltype(type)>::type.

I'm not aware of anything pre C++11, except for rolling your own variant
of std::remove_const via template specialization.

I think depending on C++11 sounds fine, since we're also depending on
C11 and people tend to use much more recent C++ versions than C
versions (so probably we could even require something higher).

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#4)
Re: Make copyObject work in C++

Peter Eisentraut <peter@eisentraut.org> writes:

AFAICT, both gcc and clang support typeof in C++ mode as well. So this
kind of renaming could be confusing.

Hm, if that's true then we should not have to do anything ...
so why is Jelte reporting a problem?

regards, tom lane

#9Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Tom Lane (#8)
Re: Make copyObject work in C++

On Mon, 8 Dec 2025 at 15:51, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Peter Eisentraut <peter@eisentraut.org> writes:

AFAICT, both gcc and clang support typeof in C++ mode as well. So this
kind of renaming could be confusing.

Hm, if that's true then we should not have to do anything ...
so why is Jelte reporting a problem?

Seems it's related to -std=c++17 vs -std=gnu++17. I was compiling my
code with the former, which throws the error in question[1]https://godbolt.org/z/fz567hs1r. Compiling
with the latter works fine[2]https://godbolt.org/z/cq1se55bn.

So I guess it depends what we want to require from C++ extensions.
Should we require them to compile with gnu extensions? My opinion on
that would be no.

[1]: https://godbolt.org/z/fz567hs1r
[2]: https://godbolt.org/z/cq1se55bn

#10Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#3)
Re: Make copyObject work in C++

On Mon, 8 Dec 2025 at 08:57, Peter Eisentraut <peter@eisentraut.org> wrote:

In the long run, I would like to change copyObject() to use
typeof_unqual instead, because that handles qualifiers more correctly.
(Currently, copyObject() of a const-qualified pointer results in a
const-qualified pointer, which is nonsensical because the reason you
made the copy is that you can modify it.) See attached patch for an
example. Does C++ have something that is semantically similar to that?

Yes, there's a std::remove_cv, std::remove_const, and std::remove_volatile[1]https://en.cppreference.com/w/cpp/types/remove_cv.html.

[1]: https://en.cppreference.com/w/cpp/types/remove_cv.html

#11Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Jelte Fennema-Nio (#5)
Re: Make copyObject work in C++

On Mon Dec 8, 2025 at 9:11 AM CET, Jelte Fennema-Nio wrote:

Went with defining pg_exprtype (pg_typeof already exists). Undefining
typeof seemed a bit heavy-handed. Especially since I think it would be
nice to backport this so C++ extensions can use copyObject directly.

Rebased version of this patchset after conflicts from 315342ffed.

Attachments:

v3-0001-Make-copyObject-work-in-C.patchtext/x-patch; charset=utf-8; name=v3-0001-Make-copyObject-work-in-C.patchDownload+15-3
v3-0002-Use-pg_exprtype-instead-of-typeof.patchtext/x-patch; charset=utf-8; name=v3-0002-Use-pg_exprtype-instead-of-typeof.patchDownload+8-9
#12Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#1)
Re: Make copyObject work in C++

On 05.12.25 15:46, Jelte Fennema-Nio wrote:

Calling copyObject fails in C++ with an error like in most setups:

error: use of undeclared identifier 'typeof'; did you mean 'typeid'

This is due to the C compiler supporting used to compile postgres
supporting typeof, but that function actually not being present in the
C++ compiler. This fixes that by using decltype instead of typeof when
including the header in C++.

Realized because of Thomas' not about how much of our headers should
work in C++, and remembering I hit this specific problem myself.

I think it might be good to create a test extension written in C++, like
under src/test/modules/, and sprinkle it with various constructs like
copyObject() and static assertions, and whatever else we find that is
possibly problematic. Then patches like this one would be much easier
to analyze and test and keep working in the future.

This would probably require resolving
<https://commitfest.postgresql.org/patch/5885/&gt; first.

#13Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#12)
Re: Make copyObject work in C++

On Tue Dec 16, 2025 at 1:28 PM CET, Peter Eisentraut wrote:

I think it might be good to create a test extension written in C++, like
under src/test/modules/, and sprinkle it with various constructs like
copyObject() and static assertions, and whatever else we find that is
possibly problematic.

Attached is a patchset that does that. It required a few more fixes to
make the extension compile on MSVC too.

Attachments:

v4-0003-Revert-Replace-pg_restrict-by-standard-restrict.patchtext/x-patch; charset=utf-8; name=v4-0003-Revert-Replace-pg_restrict-by-standard-restrict.patchDownload+53-37
v4-0004-tests-Add-a-test-C-extension-module.patchtext/x-patch; charset=utf-8; name=v4-0004-tests-Add-a-test-C-extension-module.patchDownload+140-9
v4-0001-Make-copyObject-work-in-C.patchtext/x-patch; charset=utf-8; name=v4-0001-Make-copyObject-work-in-C.patchDownload+15-3
v4-0002-Use-pg_exprtype-instead-of-typeof.patchtext/x-patch; charset=utf-8; name=v4-0002-Use-pg_exprtype-instead-of-typeof.patchDownload+8-9
#14Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Jelte Fennema-Nio (#13)
Re: Make copyObject work in C++

On Sat Jan 3, 2026 at 10:32 AM CET, Jelte Fennema-Nio wrote:

Attached is a patchset that does that. It required a few more fixes to
make the extension compile on MSVC too.

Rebased after Peter merged the C++ improvements from the other thread.

Attachments:

v5-0001-Make-copyObject-work-in-C.patchtext/x-patch; charset=utf-8; name=v5-0001-Make-copyObject-work-in-C.patchDownload+15-3
v5-0002-Use-pg_exprtype-instead-of-typeof.patchtext/x-patch; charset=utf-8; name=v5-0002-Use-pg_exprtype-instead-of-typeof.patchDownload+8-9
v5-0003-Revert-Replace-pg_restrict-by-standard-restrict.patchtext/x-patch; charset=utf-8; name=v5-0003-Revert-Replace-pg_restrict-by-standard-restrict.patchDownload+53-37
v5-0004-tests-Add-a-test-C-extension-module.patchtext/x-patch; charset=utf-8; name=v5-0004-tests-Add-a-test-C-extension-module.patchDownload+141-9
#15Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#14)
Re: Make copyObject work in C++

On 10.01.26 12:09, Jelte Fennema-Nio wrote:

On Sat Jan 3, 2026 at 10:32 AM CET, Jelte Fennema-Nio wrote:

Attached is a patchset that does that. It required a few more fixes to
make the extension compile on MSVC too.

Rebased after Peter merged the C++ improvements from the other thread.

I have a couple of comments on the sample extension module.

I think this module should have a runtime test, too. Otherwise you
don't know that you got the linkage correct, or whether this works at
all. It doesn't have to do much, like it could literally be a + b, and
it could evolve in the future to test hooks, _PG_init, etc.

Let's put a README file in the module's directory instead of putting the
explanation into the Makefile/meson.build.

I wonder if the module's build integration would work correctly in the
autoconf/makefile case if no C++ is available. AFAICT, it would fail to
build with g++ not found or similar.

AFAICT, the minimum changes to get a minimum test module to work are

- fix for "restrict", recently committed
- disable warning about zero-length arrays, seems trivial
- named designated initializers

I learned that named designated initializers in C++ are not allowed to
be specified out of order, so they are not a full equivalent to the C
syntax. This could be a problem for example if someone wanted in the
future to have something like

PG_MODULE_MAGIC_EXT(.threads_supported = true)

(while not specifying the leading .name and .version fields).

I think for now the easiest fix would be to just not use the named
initializers in the definition of PG_MODULE_MAGIC_DATA. Then we don't
need to require C++20 and have that additional code. In the future, we
might need a different solution more suitable for C++.

The use of -std=c++11 for CI is a valid idea; I have often wanted that
for C as well. But conversely we also want to allow testing optional
extension and future C standard features. So we need a comprehensive
solution there that covers both ends and both languages. Let's leave
that out for now and think about it separately.

#16Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#15)
Re: Make copyObject work in C++

On Wed, 14 Jan 2026 at 16:59, Peter Eisentraut <peter@eisentraut.org> wrote:

I think this module should have a runtime test, too. Otherwise you
don't know that you got the linkage correct, or whether this works at
all. It doesn't have to do much, like it could literally be a + b, and
it could evolve in the future to test hooks, _PG_init, etc.

Done

Let's put a README file in the module's directory instead of putting the
explanation into the Makefile/meson.build.

Done

I wonder if the module's build integration would work correctly in the
autoconf/makefile case if no C++ is available. AFAICT, it would fail to
build with g++ not found or similar.

Changed this to check that if CXX is g++, the command is also actually
available before including the module for the build.

AFAICT, the minimum changes to get a minimum test module to work are

- fix for "restrict", recently committed
- disable warning about zero-length arrays, seems trivial
- named designated initializers

Correct, I've now restructured the commits to have the module
introduction as the first one. Then all the other commits, both fix a
macro to work in C++ and add some usage of those macros as coverage to
the previously added module.

I learned that named designated initializers in C++ are not allowed to
be specified out of order, so they are not a full equivalent to the C
syntax. This could be a problem for example if someone wanted in the
future to have something like

PG_MODULE_MAGIC_EXT(.threads_supported = true)

(while not specifying the leading .name and .version fields).

This would still work fine, because fields are left out. The problem
occurs when defining values for fields, but in a different order than
the fields are specified in the struct (so e.g. by putting .version
before .name). The reason for that is related to destructor ordering.

I think for now the easiest fix would be to just not use the named
initializers in the definition of PG_MODULE_MAGIC_DATA. Then we don't
need to require C++20 and have that additional code. In the future, we
might need a different solution more suitable for C++.

There is a small problem with this though. Using both designated an
non-designated initializers, is not valid standard C++. I even get a
warning (but no error) about that with clang:

../src/test/modules/test_cplusplusext/test_cplusplusext.cpp:24:2: warning: mixture of designated and non-designated initializers in the same initializer list is a C99 extension [-Wc99-designator]

In C mixing them is allowed just fine.

Sadly that means that C++ extensions (even when compiled for C++20)
shouldn't use PG_MODULE_MAGIC_EXT with designated initializers at all.
I've updated the documentation to reflect that. I agree that it's better
to avoid requiring C++20 on MSVC (at least for now).

The use of -std=c++11 for CI is a valid idea; I have often wanted that
for C as well. But conversely we also want to allow testing optional
extension and future C standard features. So we need a comprehensive
solution there that covers both ends and both languages. Let's leave
that out for now and think about it separately.

Removed

Attachments:

v6-0001-tests-Add-a-test-C-extension-module.patchtext/x-patch; charset=utf-8; name=v6-0001-tests-Add-a-test-C-extension-module.patchDownload+174-6
v6-0002-Support-using-copyObject-in-C.patchtext/x-patch; charset=utf-8; name=v6-0002-Support-using-copyObject-in-C.patchDownload+21-3
v6-0003-Use-pg_exprtype-instead-of-typeof.patchtext/x-patch; charset=utf-8; name=v6-0003-Use-pg_exprtype-instead-of-typeof.patchDownload+8-9
v6-0004-Support-using-StaticAssert-macros-in-C.patchtext/x-patch; charset=utf-8; name=v6-0004-Support-using-StaticAssert-macros-in-C.patchDownload+11-3
v6-0005-Support-using-list_make-macros-in-C.patchtext/x-patch; charset=utf-8; name=v6-0005-Support-using-list_make-macros-in-C.patchDownload+52-6
#17Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#16)
Re: Make copyObject work in C++

On 17.01.26 16:25, Jelte Fennema-Nio wrote:

AFAICT, the minimum changes to get a minimum test module to work are

- fix for "restrict", recently committed
- disable warning about zero-length arrays, seems trivial
- named designated initializers

Correct, I've now restructured the commits to have the module
introduction as the first one. Then all the other commits, both fix a
macro to work in C++ and add some usage of those macros as coverage to
the previously added module.

I have split your first patch further. For a start, I left out the
PG_MODULE_MAGIC*-related changes and disabled the module under MSVC.
This has been committed. I plan to let the buildfarm run with it for a
day or two and then add in the basic MSVC support.

I implemented a different solution for checking whether C++ is available
under configure. The runtime check from the makefile looked a bit
fragile. This way, we now have a "have_cxx" variable available in both
meson and makefiles.

#18Andres Freund
andres@anarazel.de
In reply to: Peter Eisentraut (#17)
Re: Make copyObject work in C++

On 2026-01-20 17:28:00 +0100, Peter Eisentraut wrote:

On 17.01.26 16:25, Jelte Fennema-Nio wrote:

AFAICT, the minimum changes to get a minimum test module to work are

- fix for "restrict", recently committed
- disable warning about zero-length arrays, seems trivial
- named designated initializers

Correct, I've now restructured the commits to have the module
introduction as the first one. Then all the other commits, both fix a
macro to work in C++ and add some usage of those macros as coverage to
the previously added module.

I have split your first patch further. For a start, I left out the
PG_MODULE_MAGIC*-related changes and disabled the module under MSVC. This
has been committed. I plan to let the buildfarm run with it for a day or
two and then add in the basic MSVC support.

Seems like billbug doesn't like this:

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=billbug&amp;dt=2026-01-20%2016%3A00%3A02

gmake[1]: Entering directory '/home/marcel/build-farm-20/buildroot/HEAD/pgsql.build/src/test/modules/test_cplusplusext'
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -I. -I. -I../../../../src/include -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS -I/usr/openssl/3/include -I/usr/include/libxml2 -c -o test_cplusplusext.o test_cplusplusext.cpp
In file included from ../../../../src/include/postgres.h:48,
from test_cplusplusext.cpp:18:
../../../../src/include/c.h:158:21: error: '_Noreturn' does not name a type; did you mean 'pg_noreturn'?
158 | #define pg_noreturn _Noreturn
| ^~~~~~~~~
../../../../src/include/c.h:918:1: note: in expansion of macro 'pg_noreturn'
918 | pg_noreturn extern void ExceptionalCondition(const char *conditionName,
| ^~~~~~~~~~~
../../../../src/include/lib/stringinfo.h: In function 'void initStringInfoFromString(StringInfo, char*, int)':
../../../../src/include/c.h:890:25: error: 'ExceptionalCondition' was not declared in this scope
890 | ExceptionalCondition(#condition, __FILE__, __LINE__); \\
| ^~~~~~~~~~~~~~~~~~~~
../../../../src/include/lib/stringinfo.h:177:9: note: in expansion of macro 'Assert'
177 | Assert(data[len] == '\\0');
| ^~~~~~
../../../../src/include/utils/elog.h: At global scope:
../../../../src/include/c.h:158:21: error: '_Noreturn' does not name a type; did you mean 'pg_noreturn'?
158 | #define pg_noreturn _Noreturn
| ^~~~~~~~~
../../../../src/include/utils/elog.h:471:1: note: in expansion of macro 'pg_noreturn'
471 | pg_noreturn extern void ReThrowError(ErrorData *edata);
| ^~~~~~~~~~~
../../../../src/include/c.h:158:21: error: '_Noreturn' does not name a type; did you mean 'pg_noreturn'?
158 | #define pg_noreturn _Noreturn
| ^~~~~~~~~
../../../../src/include/utils/elog.h:473:1: note: in expansion of macro 'pg_noreturn'
473 | pg_noreturn extern void pg_re_throw(void);
| ^~~~~~~~~~~

Greetings,

Andres Freund

#19Peter Eisentraut
peter_e@gmx.net
In reply to: Andres Freund (#18)
Re: Make copyObject work in C++

On 20.01.26 17:38, Andres Freund wrote:

I have split your first patch further. For a start, I left out the
PG_MODULE_MAGIC*-related changes and disabled the module under MSVC. This
has been committed. I plan to let the buildfarm run with it for a day or
two and then add in the basic MSVC support.

Seems like billbug doesn't like this:

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?
nm=billbug&dt=2026-01-20%2016%3A00%3A02

gmake[1]: Entering directory '/home/marcel/build-farm-20/buildroot/HEAD/pgsql.build/src/test/modules/test_cplusplusext'
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -I. -I. -I../../../../src/include -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS -I/usr/openssl/3/include -I/usr/include/libxml2 -c -o test_cplusplusext.o test_cplusplusext.cpp
In file included from ../../../../src/include/postgres.h:48,
from test_cplusplusext.cpp:18:
../../../../src/include/c.h:158:21: error: '_Noreturn' does not name a type; did you mean 'pg_noreturn'?
158 | #define pg_noreturn _Noreturn
| ^~~~~~~~~
../../../../src/include/c.h:918:1: note: in expansion of macro 'pg_noreturn'
918 | pg_noreturn extern void ExceptionalCondition(const char *conditionName,
| ^~~~~~~~~~~

It's getting confused by _Noreturn, which is defined thus:

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define pg_noreturn _Noreturn

But apparently on these Solaris-related platforms, g++ defines
__STDC_VERSION__ even in C++ mode. (Confirmed in local testing.)
Apparently, this is even allowed by the C++ standard.

So the smallest fix is probably to gate this more like this:

#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) &&
!defined(__cplusplus)
#define pg_noreturn _Noreturn

(Eventually, we could add support for C++ attributes, but one step at a
time.)

#20Andres Freund
andres@anarazel.de
In reply to: Peter Eisentraut (#19)
Re: Make copyObject work in C++

Hi,

On 2026-01-20 20:07:15 +0100, Peter Eisentraut wrote:

On 20.01.26 17:38, Andres Freund wrote:

I have split your first patch further. For a start, I left out the
PG_MODULE_MAGIC*-related changes and disabled the module under MSVC. This
has been committed. I plan to let the buildfarm run with it for a day or
two and then add in the basic MSVC support.

Seems like billbug doesn't like this:

https://buildfarm.postgresql.org/cgi-bin/show_log.pl?
nm=billbug&dt=2026-01-20%2016%3A00%3A02

gmake[1]: Entering directory '/home/marcel/build-farm-20/buildroot/HEAD/pgsql.build/src/test/modules/test_cplusplusext'
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -I. -I. -I../../../../src/include -D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS -I/usr/openssl/3/include -I/usr/include/libxml2 -c -o test_cplusplusext.o test_cplusplusext.cpp
In file included from ../../../../src/include/postgres.h:48,
from test_cplusplusext.cpp:18:
../../../../src/include/c.h:158:21: error: '_Noreturn' does not name a type; did you mean 'pg_noreturn'?
158 | #define pg_noreturn _Noreturn
| ^~~~~~~~~
../../../../src/include/c.h:918:1: note: in expansion of macro 'pg_noreturn'
918 | pg_noreturn extern void ExceptionalCondition(const char *conditionName,
| ^~~~~~~~~~~

It's getting confused by _Noreturn, which is defined thus:

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define pg_noreturn _Noreturn

But apparently on these Solaris-related platforms, g++ defines
__STDC_VERSION__ even in C++ mode. (Confirmed in local testing.)
Apparently, this is even allowed by the C++ standard.

Heh. Pretty odd to do that only on some platforms...

So the smallest fix is probably to gate this more like this:

#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) &&
!defined(__cplusplus)
#define pg_noreturn _Noreturn

(Eventually, we could add support for C++ attributes, but one step at a
time.)

Makes sense to me.

Greetings,

Andres Freund

#21Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#17)
#22Andres Freund
andres@anarazel.de
In reply to: Jelte Fennema-Nio (#21)
#23Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Andres Freund (#22)
#24Andres Freund
andres@anarazel.de
In reply to: Jelte Fennema-Nio (#23)
#25Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#23)
#26Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#25)
#27Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Andres Freund (#24)
#28Bryan Green
dbryan.green@gmail.com
In reply to: Jelte Fennema-Nio (#21)
#29Peter Eisentraut
peter_e@gmx.net
In reply to: Bryan Green (#28)
#30Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Andres Freund (#24)
#31Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#30)
#32Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#30)
#33Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#32)
#34Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Jelte Fennema-Nio (#33)
#35Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#34)
#36Jelte Fennema-Nio
postgres@jeltef.nl
In reply to: Peter Eisentraut (#35)
#37Peter Eisentraut
peter_e@gmx.net
In reply to: Jelte Fennema-Nio (#34)
#38Peter Eisentraut
peter_e@gmx.net
In reply to: Peter Eisentraut (#37)
#39Peter Eisentraut
peter_e@gmx.net
In reply to: Peter Eisentraut (#38)