🌐 AI搜索 & 代理 主页
Skip to content

Commit 97e04c7

Browse files
committed
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
1 parent 266543a commit 97e04c7

File tree

4 files changed

+11
-25
lines changed

4 files changed

+11
-25
lines changed

src/backend/access/common/toast_internals.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,9 @@ toast_save_datum(Relation rel, Datum value,
287287
bool t_isnull[3] = {0};
288288
union
289289
{
290-
struct varlena hdr;
290+
alignas(int32) struct varlena hdr;
291291
/* this is to make the union big enough for a chunk: */
292292
char data[TOAST_MAX_CHUNK_SIZE + VARHDRSZ];
293-
/* ensure union is aligned well enough: */
294-
int32 align_it;
295293
} chunk_data;
296294
int32 chunk_size;
297295

src/backend/commands/async.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,14 +1987,10 @@ asyncQueueProcessPageEntries(QueuePosition *current,
19871987
/*
19881988
* We copy the entries into a local buffer to avoid holding the SLRU lock
19891989
* while we transmit them to our frontend. The local buffer must be
1990-
* adequately aligned, so use a union.
1990+
* adequately aligned.
19911991
*/
1992-
union
1993-
{
1994-
char buf[QUEUE_PAGESIZE];
1995-
AsyncQueueEntry align;
1996-
} local_buf;
1997-
char *local_buf_end = local_buf.buf;
1992+
alignas(AsyncQueueEntry) char local_buf[QUEUE_PAGESIZE];
1993+
char *local_buf_end = local_buf;
19981994

19991995
slotno = SimpleLruReadPage_ReadOnly(NotifyCtl, curpage,
20001996
InvalidTransactionId);
@@ -2082,8 +2078,8 @@ asyncQueueProcessPageEntries(QueuePosition *current,
20822078
* Now that we have let go of the SLRU bank lock, send the notifications
20832079
* to our backend
20842080
*/
2085-
Assert(local_buf_end - local_buf.buf <= BLCKSZ);
2086-
for (char *p = local_buf.buf; p < local_buf_end;)
2081+
Assert(local_buf_end - local_buf <= BLCKSZ);
2082+
for (char *p = local_buf; p < local_buf_end;)
20872083
{
20882084
AsyncQueueEntry *qe = (AsyncQueueEntry *) p;
20892085

src/backend/storage/large_object/inv_api.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -556,11 +556,9 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
556556
bool pfreeit;
557557
union
558558
{
559-
bytea hdr;
559+
alignas(int32) bytea hdr;
560560
/* this is to make the union big enough for a LO data chunk: */
561561
char data[LOBLKSIZE + VARHDRSZ];
562-
/* ensure union is aligned well enough: */
563-
int32 align_it;
564562
} workbuf = {0};
565563
char *workb = VARDATA(&workbuf.hdr);
566564
HeapTuple newtup;
@@ -747,11 +745,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
747745
Form_pg_largeobject olddata;
748746
union
749747
{
750-
bytea hdr;
748+
alignas(int32) bytea hdr;
751749
/* this is to make the union big enough for a LO data chunk: */
752750
char data[LOBLKSIZE + VARHDRSZ];
753-
/* ensure union is aligned well enough: */
754-
int32 align_it;
755751
} workbuf = {0};
756752
char *workb = VARDATA(&workbuf.hdr);
757753
HeapTuple newtup;

src/include/c.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,15 +1117,11 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
11171117
* Use this, not "char buf[BLCKSZ]", to declare a field or local variable
11181118
* holding a page buffer, if that page might be accessed as a page. Otherwise
11191119
* the variable might be under-aligned, causing problems on alignment-picky
1120-
* hardware. We include both "double" and "int64" in the union to ensure that
1121-
* the compiler knows the value must be MAXALIGN'ed (cf. configure's
1122-
* computation of MAXIMUM_ALIGNOF).
1120+
* hardware.
11231121
*/
1124-
typedef union PGAlignedBlock
1122+
typedef struct PGAlignedBlock
11251123
{
1126-
char data[BLCKSZ];
1127-
double force_align_d;
1128-
int64 force_align_i64;
1124+
alignas(MAXIMUM_ALIGNOF) char data[BLCKSZ];
11291125
} PGAlignedBlock;
11301126

11311127
/*

0 commit comments

Comments
 (0)