1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-24 00:23:06 +03:00

C11 alignas instead of unions

This changes a few union members that only existed to ensure
alignments and replaces them with the C11 alignas specifier.

This change only uses fundamental alignments (meaning approximately
alignments of basic types), which all C11 compilers must support.
There are opportunities for similar changes using extended alignments,
for example in PGIOAlignedBlock, but these are not necessarily
supported by all compilers, so they are kept as a separate change.

Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/46f05236-d4d4-4b4e-84d4-faa500f14691%40eisentraut.org
This commit is contained in:
Peter Eisentraut
2025-11-21 09:57:06 +01:00
parent 266543a620
commit 97e04c74be
4 changed files with 11 additions and 25 deletions

View File

@@ -287,11 +287,9 @@ toast_save_datum(Relation rel, Datum value,
bool t_isnull[3] = {0}; bool t_isnull[3] = {0};
union union
{ {
struct varlena hdr; alignas(int32) struct varlena hdr;
/* this is to make the union big enough for a chunk: */ /* this is to make the union big enough for a chunk: */
char data[TOAST_MAX_CHUNK_SIZE + VARHDRSZ]; char data[TOAST_MAX_CHUNK_SIZE + VARHDRSZ];
/* ensure union is aligned well enough: */
int32 align_it;
} chunk_data; } chunk_data;
int32 chunk_size; int32 chunk_size;

View File

@@ -1987,14 +1987,10 @@ asyncQueueProcessPageEntries(QueuePosition *current,
/* /*
* We copy the entries into a local buffer to avoid holding the SLRU lock * We copy the entries into a local buffer to avoid holding the SLRU lock
* while we transmit them to our frontend. The local buffer must be * while we transmit them to our frontend. The local buffer must be
* adequately aligned, so use a union. * adequately aligned.
*/ */
union alignas(AsyncQueueEntry) char local_buf[QUEUE_PAGESIZE];
{ char *local_buf_end = local_buf;
char buf[QUEUE_PAGESIZE];
AsyncQueueEntry align;
} local_buf;
char *local_buf_end = local_buf.buf;
slotno = SimpleLruReadPage_ReadOnly(NotifyCtl, curpage, slotno = SimpleLruReadPage_ReadOnly(NotifyCtl, curpage,
InvalidTransactionId); InvalidTransactionId);
@@ -2082,8 +2078,8 @@ asyncQueueProcessPageEntries(QueuePosition *current,
* Now that we have let go of the SLRU bank lock, send the notifications * Now that we have let go of the SLRU bank lock, send the notifications
* to our backend * to our backend
*/ */
Assert(local_buf_end - local_buf.buf <= BLCKSZ); Assert(local_buf_end - local_buf <= BLCKSZ);
for (char *p = local_buf.buf; p < local_buf_end;) for (char *p = local_buf; p < local_buf_end;)
{ {
AsyncQueueEntry *qe = (AsyncQueueEntry *) p; AsyncQueueEntry *qe = (AsyncQueueEntry *) p;

View File

@@ -556,11 +556,9 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
bool pfreeit; bool pfreeit;
union union
{ {
bytea hdr; alignas(int32) bytea hdr;
/* this is to make the union big enough for a LO data chunk: */ /* this is to make the union big enough for a LO data chunk: */
char data[LOBLKSIZE + VARHDRSZ]; char data[LOBLKSIZE + VARHDRSZ];
/* ensure union is aligned well enough: */
int32 align_it;
} workbuf = {0}; } workbuf = {0};
char *workb = VARDATA(&workbuf.hdr); char *workb = VARDATA(&workbuf.hdr);
HeapTuple newtup; HeapTuple newtup;
@@ -747,11 +745,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Form_pg_largeobject olddata; Form_pg_largeobject olddata;
union union
{ {
bytea hdr; alignas(int32) bytea hdr;
/* this is to make the union big enough for a LO data chunk: */ /* this is to make the union big enough for a LO data chunk: */
char data[LOBLKSIZE + VARHDRSZ]; char data[LOBLKSIZE + VARHDRSZ];
/* ensure union is aligned well enough: */
int32 align_it;
} workbuf = {0}; } workbuf = {0};
char *workb = VARDATA(&workbuf.hdr); char *workb = VARDATA(&workbuf.hdr);
HeapTuple newtup; HeapTuple newtup;

View File

@@ -1117,15 +1117,11 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
* Use this, not "char buf[BLCKSZ]", to declare a field or local variable * Use this, not "char buf[BLCKSZ]", to declare a field or local variable
* holding a page buffer, if that page might be accessed as a page. Otherwise * holding a page buffer, if that page might be accessed as a page. Otherwise
* the variable might be under-aligned, causing problems on alignment-picky * the variable might be under-aligned, causing problems on alignment-picky
* hardware. We include both "double" and "int64" in the union to ensure that * hardware.
* the compiler knows the value must be MAXALIGN'ed (cf. configure's
* computation of MAXIMUM_ALIGNOF).
*/ */
typedef union PGAlignedBlock typedef struct PGAlignedBlock
{ {
char data[BLCKSZ]; alignas(MAXIMUM_ALIGNOF) char data[BLCKSZ];
double force_align_d;
int64 force_align_i64;
} PGAlignedBlock; } PGAlignedBlock;
/* /*