Обсуждение: Make copyObject work in C++
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.
Вложения
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
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?
Вложения
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.
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.
Вложения
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
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).
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
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]. Compiling with the latter works fine[2]. 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
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]. [1]: https://en.cppreference.com/w/cpp/types/remove_cv.html
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.