From: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
To: Andres Freund <andres@anarazel.de>
To: pgsql-hackers@postgresql.org, Thomas Munro <thomas.munro@enterprisedb.com>
Subject: Re: Large writable variables
Date: Wed, 17 Oct 2018 21:06:13 +0200
Message-ID: <200cf391-4a60-4c69-85d8-c715c7bce4de@2ndquadrant.com> (raw)
In-Reply-To: <20181016063013.kigj6e5pqx6n75y3@alap3.anarazel.de>
References: <20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de>
<20181016045051.wr35ubb6h7h3ee2b@alap3.anarazel.de>
<20181016050200.c65yjz2qgxulgouv@alap3.anarazel.de>
<20181016063013.kigj6e5pqx6n75y3@alap3.anarazel.de>
On 16/10/2018 08:30, Andres Freund wrote:
> This just reminded me that a couple times I wanted a cast that casts
> away const, but otherwise makes sure the type stays the same. I don't
> think there's a way to do that in C, but we can write one that verifies
> the cast doesn't do something bad if gcc is used:
>
> #if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P)
> #define unconstify(cst, var) StaticAssertExpr(__builtin_types_compatible_p(__typeof(var), const cst), "wrong cast"), (cst) (var)
> #else
> #define unconstify(cst, var) ((cst) (var))
> #endif
>
> Does anybody besides me see value in adding a cleaned up version of
> that?
I've had the attached patch lying around. As you can see there, there
are a few places where it could be useful, but not too many.
The name CONST_CAST() is adapted from C++.
Your version with __builtin_types_compatible_p() doesn't work for
casting between char * and const char *, so it wouldn't be very useful.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:0001-Add-CONST_CAST-macro.patch (text/plain, 4.8K) download
From 31576b37687f44fc14bcf0990eb489466b74bf29 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 23 May 2018 09:10:51 -0400
Subject: [PATCH] Add CONST_CAST macro
---
src/backend/utils/adt/json.c | 4 ++--
src/backend/utils/adt/misc.c | 2 +-
src/backend/utils/adt/varlena.c | 4 ++--
src/backend/utils/fmgr/dfmgr.c | 4 ++--
src/include/c.h | 6 ++++++
src/interfaces/libpq/pqexpbuffer.c | 2 +-
src/port/win32setlocale.c | 2 +-
7 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.cindex 6f0fe94d63..6190b01dd2 100644--- a/src/backend/utils/adt/json.c+++ b/src/backend/utils/adt/json.c@@ -207,12 +207,12 @@ IsValidJsonNumber(const char *str, int len)
*/
if (*str == '-')
{
- dummy_lex.input = (char *) str + 1;+ dummy_lex.input = CONST_CAST(char *, str) + 1;
dummy_lex.input_length = len - 1;
}
else
{
- dummy_lex.input = (char *) str;+ dummy_lex.input = CONST_CAST(char *, str);
dummy_lex.input_length = len;
}
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.cindex 6ea3679835..179ba81880 100644--- a/src/backend/utils/adt/misc.c+++ b/src/backend/utils/adt/misc.c@@ -423,7 +423,7 @@ pg_get_keywords(PG_FUNCTION_ARGS)
HeapTuple tuple;
/* cast-away-const is ugly but alternatives aren't much better */
- values[0] = (char *) ScanKeywords[funcctx->call_cntr].name;+ values[0] = CONST_CAST(char *, ScanKeywords[funcctx->call_cntr].name);
switch (ScanKeywords[funcctx->call_cntr].category)
{
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.cindex a5e812d026..a98ec2f8df 100644--- a/src/backend/utils/adt/varlena.c+++ b/src/backend/utils/adt/varlena.c@@ -182,7 +182,7 @@ char *
text_to_cstring(const text *t)
{
/* must cast away the const, unfortunately */
- text *tunpacked = pg_detoast_datum_packed((struct varlena *) t);+ text *tunpacked = pg_detoast_datum_packed(CONST_CAST(text *, t));
int len = VARSIZE_ANY_EXHDR(tunpacked);
char *result;
@@ -213,7 +213,7 @@ void
text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
{
/* must cast away the const, unfortunately */
- text *srcunpacked = pg_detoast_datum_packed((struct varlena *) src);+ text *srcunpacked = pg_detoast_datum_packed(CONST_CAST(text *, src));
size_t src_len = VARSIZE_ANY_EXHDR(srcunpacked);
if (dst_len > 0)
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.cindex 4a5cc7cfc7..b2ff7aef35 100644--- a/src/backend/utils/fmgr/dfmgr.c+++ b/src/backend/utils/fmgr/dfmgr.c@@ -126,7 +126,7 @@ load_external_function(const char *filename, const char *funcname,
* should declare its second argument as "const char *", but older
* platforms might not, so for the time being we just cast away const.
*/
- retval = (PGFunction) dlsym(lib_handle, (char *) funcname);+ retval = (PGFunction) dlsym(lib_handle, CONST_CAST(char *, funcname));
if (retval == NULL && signalNotFound)
ereport(ERROR,
@@ -175,7 +175,7 @@ PGFunction
lookup_external_function(void *filehandle, const char *funcname)
{
/* as above, cast away const for the time being */
- return (PGFunction) dlsym(filehandle, (char *) funcname);+ return (PGFunction) dlsym(filehandle, CONST_CAST(char *, funcname));
}
diff --git a/src/include/c.h b/src/include/c.hindex 4a757bc8ea..6341b2512f 100644--- a/src/include/c.h+++ b/src/include/c.h@@ -208,6 +208,12 @@
#define unlikely(x) ((x) != 0)
#endif
+/*+ * Safer casting -- use this for casting away const or volatile. It ensures+ * that the source and target types are otherwise compatible.+ */+#define CONST_CAST(t, x) ((void)((t)0 == (x)), (t)(x))+
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.cindex 43c36c3bff..4015b58a08 100644--- a/src/interfaces/libpq/pqexpbuffer.c+++ b/src/interfaces/libpq/pqexpbuffer.c@@ -57,7 +57,7 @@ markPQExpBufferBroken(PQExpBuffer str)
* to put oom_buffer in read-only storage, so that anyone who tries to
* scribble on a broken PQExpBuffer will get a failure.
*/
- str->data = (char *) oom_buffer;+ str->data = CONST_CAST(char *, oom_buffer);
str->len = 0;
str->maxlen = 0;
}
diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.cindex 0597c2afca..3514b5606a 100644--- a/src/port/win32setlocale.c+++ b/src/port/win32setlocale.c@@ -183,7 +183,7 @@ pgwin32_setlocale(int category, const char *locale)
* forbidden to modify, so casting away the "const" is innocuous.
*/
if (result)
- result = (char *) map_locale(locale_map_result, result);+ result = CONST_CAST(char *, map_locale(locale_map_result, result));
return result;
}
--
2.19.1
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: pgsql-hackers@postgresql.org
Cc: peter.eisentraut@2ndquadrant.com, andres@anarazel.de, thomas.munro@enterprisedb.com
Subject: Re: Large writable variables
In-Reply-To: <200cf391-4a60-4c69-85d8-c715c7bce4de@2ndquadrant.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox