unconstify()/unvolatize() vs g++/clang++
Hi,
AFAICS you can't use unconstify()/unvolatize() in a static inline
function in a .h file, or in a .cpp file, because
__builtin_types_compatible_p is only available in C, not C++. Seems
like a reasonable thing to want to be able to do, no? I'm not
immediately sure what the right fix is; would #if
defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) && !defined(__cplusplus)
around the relevant versions of constify()/unvolatize() be too easy?
HAVE__BUILTIN_TYPES_COMPATIBLE_P is also tested in relptr.h, but only
for further preprocessor stuff, not in functions that the compiler
will see, so cpluspluscheck doesn't have anything to reject, and
nothing will break unless someone writing C++ code actually tries to
use relptr_access(). I think we can live with that one?
On 11.12.23 01:42, Thomas Munro wrote:
AFAICS you can't use unconstify()/unvolatize() in a static inline
function in a .h file, or in a .cpp file, because
__builtin_types_compatible_p is only available in C, not C++. Seems
like a reasonable thing to want to be able to do, no? I'm not
immediately sure what the right fix is; would #if
defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) && !defined(__cplusplus)
around the relevant versions of constify()/unvolatize() be too easy?
That seems right to me.
If you are slightly more daring, you can write an alternative definition
in C++ using const_cast?
On Mon, Dec 11, 2023 at 10:17 PM Peter Eisentraut <peter@eisentraut.org> wrote:
If you are slightly more daring, you can write an alternative definition
in C++ using const_cast?
Oh, yeah, right, that works for my case. I can't think of any
reasons not to do this, but IANAC++L.
Attachments:
0001-Define-unconstify-and-unvolatize-for-C.patchapplication/octet-stream; name=0001-Define-unconstify-and-unvolatize-for-C.patchDownload
From 21b162fb6bfb124758930442db8f47e1c666a59a Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Mon, 11 Dec 2023 22:54:31 +1300
Subject: [PATCH] Define unconstify() and unvolatize() for C++.
These two macros wouldn't work if used in a header seen by g++/clang++,
because __builtin_types_compatible_p is only available in C. Redirect
to standard C++ const_cast in C++ code.
Suggested-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/CA%2BhUKGK3OXFjkOyZiw-DgL2bUqk9by1uGuCnViJX786W%2BfyDSw%40mail.gmail.com
diff --git a/src/include/c.h b/src/include/c.h
index 82f8e9d4c7..4b0f5138d8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1245,7 +1245,10 @@ typedef union PGAlignedXLogBlock
* Note that this only works in function scope, not for global variables (it'd
* be nice, but not trivial, to improve that).
*/
-#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P)
+#if defined(__cplusplus)
+#define unconstify(underlying_type, expr) const_cast<underlying_type>(expr)
+#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), \
"wrong cast"), \
--
2.43.0
On Mon, Dec 11, 2023 at 11:32 PM Thomas Munro <thomas.munro@gmail.com> wrote:
On Mon, Dec 11, 2023 at 10:17 PM Peter Eisentraut <peter@eisentraut.org> wrote:
If you are slightly more daring, you can write an alternative definition
in C++ using const_cast?Oh, yeah, right, that works for my case. I can't think of any
reasons not to do this, but IANAC++L.
And pushed. Thanks!