Re: Confused static assertion implementation

From: Peter Eisentraut <peter(at)eisentraut(dot)org>
To: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Confused static assertion implementation
Date: 2025-11-18 13:31:10
Message-ID: 3264689d-ecca-4b1f-998c-2e29f344ff95@eisentraut.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 14.11.25 03:13, Thomas Munro wrote:
> I won't be surprised if Peter (CC'd) already has a patch for this in
> his C11 incubation branch, but if not, maybe this will be useful.
>
> While experimenting with threads and atomics on various systems, I
> didn't like the way our macros failed in the ancient fallback code on
> Visual Studio. That only seems to be necessary for
> StaticAssertExpr(), the rarest case. That led to some observations:
>
> * the meson script defines HAVE__STATIC_ASSERT if you have GCC
> statement expressions, so why not just say so with
> HAVE_STATEMENT_EXPRESSIONS, and keep ye olde fallback only for
> StaticAssertExpr()?
>
> * the configure script is different, tautological and wrong for
> (evidently hypothetical) non-GCC-compatible C11 compiler given the
> above interpretation of the macro

There is a curious, now obsolete surprise here: MSVC without C11 mode
enabled does support _Static_assert, but it does not allow it at file
scope. Our overly restrictive HAVE__STATIC_ASSERT check fails on MSVC,
but if it passed our code would have failed to compile because of the
file-scope static assertions. So this one suboptimal check covered for
a lack of a check elsewhere.

This is now obsolete; with MSVC in C11 mode, _Static_assert appears to
behave correctly.

I have found that the C standard committee is actively researching
allowing static assertions in expressions:

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3538.pdf
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3637.pdf
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3682.pdf
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3715.pdf

Those documents also contain some information about workarounds in use.

Btw., statement expressions are also in play:

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3643.htm

But it looks like the most popular workaround is to put the
static_assert in a struct declaration.

On compiler explorer, I found that this works in MSVC but produces a
warning. But in my actual PostgreSQL patches it currently fails. But
anyway, since we're talking about it now, I'm attaching my patches here.
So only 0001 through 0004 work, the remaining two are WIP. Maybe
someone can stare at 0005 long enough to find what the problem is.

> * to my knowledge we haven't written down which C++ standard our
> headers conform to anywhere, but it surely can't be older than C++11
> (I could elaborate), so I don't think we need the two __cplusplus
> implementations

Per
<https://www.postgresql.org/message-id/01a69441-af54-4822-891b-ca28e05b215a%40eisentraut.org>
it's >= C++11.

> . o O { I wonder if it's possible to write a C23/C++17-compatible
> single-argument static_assert() macro, or if you'd get stuck in a loop
> and need to use a different name... the message argument is so often
> boring/redundant... }

That would be nice, but I haven't tried it yet.

Attachment Content-Type Size
0001-Rename-AssertVariableIsOfType-to-StaticAssertVariabl.patch text/plain 28.1 KB
0002-Change-StaticAssertVariableIsOfType-to-be-a-declarat.patch text/plain 9.7 KB
0003-Remove-most-StaticAssertStmt.patch text/plain 11.6 KB
0004-Remove-StaticAssertStmt.patch text/plain 3.1 KB
0005-Portable-StaticAssertExpr.patch text/plain 7.1 KB
0006-Use-static_assert-inside-StaticAssert-macros.patch text/plain 3.1 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Eisentraut 2025-11-18 13:35:59 Re: alignas (C11)
Previous Message Vaibhav Dalvi 2025-11-18 12:59:36 Re: [PATCH] Add pg_get_subscription_ddl() function