Re: alignas (C11) - Mailing list pgsql-hackers

From Chao Li
Subject Re: alignas (C11)
Date
Msg-id 0BB3A7BC-C63A-4F85-AD1D-AE4E3D558E79@gmail.com
Whole thread Raw
In response to alignas (C11)  (Peter Eisentraut <peter@eisentraut.org>)
List pgsql-hackers

> On Nov 12, 2025, at 19:39, Peter Eisentraut <peter@eisentraut.org> wrote:
>
> Here is another patch set to sprinkle some C11 features around the
> code.  My aim is to make a little bit of use of several C11 features
> as examples and encouragement for future code, and to test compilers.
>
> Here, I'm proposing to make some use of the alignas specifier.  This takes the place of compiler extensions such as
__attribute__((aligned(a)))and __declspec(align(a)), packaged up as pg_attribute_aligned(a), which are used in a
varietyof places.  Also, we can simplify some places where unions are used to encourage alignment, and remove a few
workaroundfor lack of alignment attribute support. 
>
> Some detail notes:
>
> - Technically, compilers are only required to support alignas up to (handwaving over some terminology) the largest
alignmentof a built-in type, so maybe 8 or 16.  Support for larger alignments like alignas(PG_CACHE_LINE_SIZE) is
implementation-defined. I have split up my patches so that fundamental and extended alignments are in separate patches,
sothis could be eased into, but I'm expecting that all compilers in practical use support alignments up to
PG_IO_ALIGN_SIZE.(For MSVC, 4096 appears to be the actual limit by default, per [0], but this is independent of using
alignasor __declspec.  I haven't found any explicit documentation for clang or gcc.) 
>
> [0]: https://learn.microsoft.com/en-us/cpp/build/reference/align-section-alignment?view=msvc-170
>
> - You cannot use alignas on a typedef.  So some uses of the attribute pg_attribute_aligned() like for
PgAioUringContextor the whole int128 business cannot be converted directly.  The solution for cases like
PgAioUringContextcould be to move the alignas into the struct, but I haven't studied this code closely enough, so I'm
leavingit.  For int128, there is no straightforward solution, so I'm also leaving that as is. 
>
> (The reason for this restriction is that typedefs are supposed to be type aliases that are interchangeable.  But if
youhave two otherwise compatible typedefs with different alignments, this kind of violates the C type system and the
compilerhas to do some nonstandard magic to handle this (or fail to, see "checking for __int128 alignment bug").) 
>
> - You cannot use alignas to underalign a type.  So again, int128 cannot be handled by this.
>
> For at least these reasons, I'm leaving pg_attribute_aligned() and some of its more tricky uses in place and
unchanged.
>
<0001-Add-stdalign.h-to-c.h.patch><0002-C11-alignas-instead-of-unions.patch><0003-Use-C11-alignas-in-pg_atomic_uint64-definitions.patch><0004-C11-alignas-instead-of-unions-extended-alignments.patch>

I can confirm that with this patch, build passed on MacOS 15.6.1, and “make check” passed as well.

0001 is a minimum and straightforward change that enables the use of C11’s alignas and alignof keywords throughout the
PostgreSQLsource. 

0002 simplifies several structures/unions by using alignas, I have a couple of minor comment:

1 - 0002
```
-typedef union PGAlignedBlock
+typedef struct PGAlignedBlock
 {
-    char        data[BLCKSZ];
-    double        force_align_d;
-    int64        force_align_i64;
+    alignas(MAXIMUM_ALIGNOF) char data[BLCKSZ];
 } PGAlignedBlock;
```

As we changes PGAlignedBlock from union to structure, I think we can explicitly mention in the commit message something
like“PGAlignedBlock has the same alignment and contiguous array data, thus no ABI change”. 

2 - 0002
```
-    /* page_buffer must be adequately aligned, so use a union */
-    union
-    {
-        char        buf[QUEUE_PAGESIZE];
-        AsyncQueueEntry align;
-    }            page_buffer;
+    /* page_buffer must be adequately aligned */
+    alignas(AsyncQueueEntry) char page_buffer[QUEUE_PAGESIZE];
```

To make readers easier to understand the statement, maybe we can explicitly use alignof:

alignas(alignof(AsyncQueueEntry)) char page_buffer[QUEUE_PAGESIZE];

0003 replaces pg_attribute_aligned(8) with alignas(8), no comment.

0004 removes "#ifdef pg_attribute_aligned”, I think that just disables support of very old compilers that we might no
longercare about them, which should be okay. For 0004, the same comment as 1. 

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/







pgsql-hackers by date:

Previous
From: Alexander Korotkov
Date:
Subject: Re: Add tab completion support for WAIT FOR command
Next
From: David Geier
Date:
Subject: Re: tuple radix sort