public inbox for [email protected]
help / color / mirror / Atom feedFrom: Jelte Fennema-Nio <[email protected]>
To: Tom Lane <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Cc: Thomas Munro <[email protected]>
Subject: Re: Make copyObject work in C++
Date: Sun, 14 Dec 2025 17:56:23 +0100
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <CAGECzQR21OnnKiZO_1rLWO0-16kg1JBxnVq-wymYW0-_1cUNtg@mail.gmail.com>
<[email protected]>
<[email protected]>
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:
[text/x-patch] v3-0001-Make-copyObject-work-in-C.patch (2.1K, 2-v3-0001-Make-copyObject-work-in-C.patch)
download | inline diff:
From 4d4e137b4712b48bf3b7c5a19813c1956a28538e Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <[email protected]>
Date: Fri, 5 Dec 2025 15:37:59 +0100
Subject: [PATCH v3 1/2] 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 defining pg_exprtype which maps to
typeof or decltype depending on the compiler. While pg_typeof would have
been a more natural name, that one is already taken in our codebase as
the implementation of the pg_typeof UDF.
---
src/include/c.h | 13 +++++++++++++
src/include/nodes/nodes.h | 4 ++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/include/c.h b/src/include/c.h
index d2cdc76644c..040f2ffc32b 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -418,6 +418,19 @@
#define unlikely(x) ((x) != 0)
#endif
+/*
+ * pg_exprtype
+ * Get the type of an expression at compile time.
+ *
+ * In C++ we use decltype since typeof is not standard C++, while in C we use
+ * typeof when available.
+ */
+#if defined(__cplusplus)
+#define pg_exprtype(x) decltype(x)
+#elif defined(HAVE_TYPEOF)
+#define pg_exprtype(x) typeof(x)
+#endif
+
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index fb3957e75e5..a8f42431828 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -226,8 +226,8 @@ extern int16 *readAttrNumberCols(int numCols);
extern void *copyObjectImpl(const void *from);
/* cast result back to argument type, if supported by compiler */
-#ifdef HAVE_TYPEOF
-#define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj))
+#ifdef pg_exprtype
+#define copyObject(obj) ((pg_exprtype(obj)) copyObjectImpl(obj))
#else
#define copyObject(obj) copyObjectImpl(obj)
#endif
base-commit: c5ae07a90a0f3594e5053a26f3c99b041df427d3
--
2.52.0
[text/x-patch] v3-0002-Use-pg_exprtype-instead-of-typeof.patch (3.1K, 3-v3-0002-Use-pg_exprtype-instead-of-typeof.patch)
download | inline diff:
From 8a4b4749aa87dff7e4e40d2eeb21b84f97811738 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <[email protected]>
Date: Mon, 8 Dec 2025 08:13:51 +0100
Subject: [PATCH v3 2/2] Use pg_exprtype instead of typeof
The previous commit introduced pg_exprtype. This starts using that in a
few more places.
---
src/include/c.h | 8 ++++----
src/include/utils/relptr.h | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/include/c.h b/src/include/c.h
index 040f2ffc32b..f0800669f09 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -997,10 +997,10 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
*/
#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
#define AssertVariableIsOfType(varname, typename) \
- StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \
+ StaticAssertStmt(__builtin_types_compatible_p(pg_exprtype(varname), typename), \
CppAsString(varname) " does not have type " CppAsString(typename))
#define AssertVariableIsOfTypeMacro(varname, typename) \
- (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
+ (StaticAssertExpr(__builtin_types_compatible_p(pg_exprtype(varname), typename), \
CppAsString(varname) " does not have type " CppAsString(typename)))
#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
#define AssertVariableIsOfType(varname, typename) \
@@ -1248,11 +1248,11 @@ typedef struct PGAlignedXLogBlock
#define unvolatize(underlying_type, expr) const_cast<underlying_type>(expr)
#elif defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P)
#define unconstify(underlying_type, expr) \
- (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const underlying_type), \
+ (StaticAssertExpr(__builtin_types_compatible_p(pg_exprtype(expr), const underlying_type), \
"wrong cast"), \
(underlying_type) (expr))
#define unvolatize(underlying_type, expr) \
- (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile underlying_type), \
+ (StaticAssertExpr(__builtin_types_compatible_p(pg_exprtype(expr), volatile underlying_type), \
"wrong cast"), \
(underlying_type) (expr))
#else
diff --git a/src/include/utils/relptr.h b/src/include/utils/relptr.h
index 48e394dba71..dac61b13118 100644
--- a/src/include/utils/relptr.h
+++ b/src/include/utils/relptr.h
@@ -38,10 +38,10 @@
#define relptr_declare(type, relptrtype) \
typedef relptr(type) relptrtype
-#ifdef HAVE_TYPEOF
+#ifdef pg_exprtype
#define relptr_access(base, rp) \
(AssertVariableIsOfTypeMacro(base, char *), \
- (typeof((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \
+ (pg_exprtype((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \
(base) + (rp).relptr_off - 1))
#else
#define relptr_access(base, rp) \
@@ -68,10 +68,10 @@ relptr_store_eval(char *base, char *val)
}
}
-#ifdef HAVE_TYPEOF
+#ifdef pg_exprtype
#define relptr_store(base, rp, val) \
(AssertVariableIsOfTypeMacro(base, char *), \
- AssertVariableIsOfTypeMacro(val, typeof((rp).relptr_type)), \
+ AssertVariableIsOfTypeMacro(val, pg_exprtype((rp).relptr_type)), \
(rp).relptr_off = relptr_store_eval((base), (char *) (val)))
#else
#define relptr_store(base, rp, val) \
--
2.52.0
view thread (25+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Subject: Re: Make copyObject work in C++
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox