Обсуждение: Make copyObject work in C++

Поиск
Список
Период
Сортировка

Make copyObject work in C++

От
Jelte Fennema-Nio
Дата:
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.

Вложения

Re: Make copyObject work in C++

От
Tom Lane
Дата:
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



Re: Make copyObject work in C++

От
Peter Eisentraut
Дата:
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?
Вложения

Re: Make copyObject work in C++

От
Peter Eisentraut
Дата:
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.



Re: Make copyObject work in C++

От
"Jelte Fennema-Nio"
Дата:
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.

Вложения

Re: Make copyObject work in C++

От
David Geier
Дата:
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



Re: Make copyObject work in C++

От
Jelte Fennema-Nio
Дата:
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).



Re: Make copyObject work in C++

От
Tom Lane
Дата:
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



Re: Make copyObject work in C++

От
Jelte Fennema-Nio
Дата:
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



Re: Make copyObject work in C++

От
Jelte Fennema-Nio
Дата:
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



Re: Make copyObject work in C++

От
"Jelte Fennema-Nio"
Дата:
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.

Вложения