Change remaining StaticAssertStmt() to StaticAssertDecl()

This completes the work started by commit 75f49221c2.

In basebackup.c, changing the StaticAssertStmt to StaticAssertDecl
results in having the same StaticAssertDecl() in 2 functions.  So, it
makes more sense to move it to file scope instead.

Also, as it depends on some computations based on 2 tar blocks, define
TAR_NUM_TERMINATION_BLOCKS.

In deadlock.c, change the StaticAssertStmt to StaticAssertDecl and
keep it in the function scope.  Add new braces to avoid warning from
-Wdeclaration-after-statement.

In aset.c, change the StaticAssertStmt to StaticAssertDecl and move it
to file scope.

Finally, update the comments in c.h a bit.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Co-authored-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/aYH6ii46AvGVCB84%40ip-10-97-1-34.eu-west-3.compute.internal
This commit is contained in:
Peter Eisentraut 2026-02-16 09:13:10 +01:00
parent 351265a6c7
commit d50c86e743
4 changed files with 37 additions and 26 deletions

View file

@ -78,6 +78,11 @@ typedef struct
pg_checksum_type manifest_checksum_type;
} basebackup_options;
#define TAR_NUM_TERMINATION_BLOCKS 2
StaticAssertDecl(TAR_NUM_TERMINATION_BLOCKS * TAR_BLOCK_SIZE <= BLCKSZ,
"BLCKSZ too small for " CppAsString2(TAR_NUM_TERMINATION_BLOCKS) " tar termination blocks");
static int64 sendTablespace(bbsink *sink, char *path, Oid spcoid, bool sizeonly,
struct backup_manifest_info *manifest,
IncrementalBackupInfo *ib);
@ -382,10 +387,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink,
else
{
/* Properly terminate the tarfile. */
StaticAssertDecl(2 * TAR_BLOCK_SIZE <= BLCKSZ,
"BLCKSZ too small for 2 tar blocks");
memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
memset(sink->bbs_buffer, 0, TAR_NUM_TERMINATION_BLOCKS * TAR_BLOCK_SIZE);
bbsink_archive_contents(sink, TAR_NUM_TERMINATION_BLOCKS * TAR_BLOCK_SIZE);
/* OK, that's the end of the archive. */
bbsink_end_archive(sink);
@ -635,10 +638,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink,
}
/* Properly terminate the tar file. */
StaticAssertStmt(2 * TAR_BLOCK_SIZE <= BLCKSZ,
"BLCKSZ too small for 2 tar blocks");
memset(sink->bbs_buffer, 0, 2 * TAR_BLOCK_SIZE);
bbsink_archive_contents(sink, 2 * TAR_BLOCK_SIZE);
memset(sink->bbs_buffer, 0, TAR_NUM_TERMINATION_BLOCKS * TAR_BLOCK_SIZE);
bbsink_archive_contents(sink, TAR_NUM_TERMINATION_BLOCKS * TAR_BLOCK_SIZE);
/* OK, that's the end of the archive. */
bbsink_end_archive(sink);

View file

@ -191,11 +191,13 @@ InitDeadLockChecking(void)
* last MaxBackends entries in possibleConstraints[] are reserved as
* output workspace for FindLockCycle.
*/
StaticAssertStmt(MAX_BACKENDS_BITS <= (32 - 3),
"MAX_BACKENDS_BITS too big for * 4");
maxPossibleConstraints = MaxBackends * 4;
possibleConstraints =
(EDGE *) palloc(maxPossibleConstraints * sizeof(EDGE));
{
StaticAssertDecl(MAX_BACKENDS_BITS <= (32 - 3),
"MAX_BACKENDS_BITS too big for * 4");
maxPossibleConstraints = MaxBackends * 4;
possibleConstraints =
(EDGE *) palloc(maxPossibleConstraints * sizeof(EDGE));
}
MemoryContextSwitchTo(oldcxt);
}

View file

@ -87,6 +87,10 @@
#define ALLOC_CHUNK_FRACTION 4
/* We allow chunks to be at most 1/4 of maxBlockSize (less overhead) */
/* ALLOC_CHUNK_LIMIT must be equal to ALLOCSET_SEPARATE_THRESHOLD */
StaticAssertDecl(ALLOC_CHUNK_LIMIT == ALLOCSET_SEPARATE_THRESHOLD,
"ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
/*--------------------
* The first block allocated for an allocset has size initBlockSize.
* Each time we have to allocate another block, we double the block size
@ -501,12 +505,6 @@ AllocSetContextCreateInternal(MemoryContext parent,
* requests that are all the maximum chunk size we will waste at most
* 1/8th of the allocated space.
*
* Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD.
*/
StaticAssertStmt(ALLOC_CHUNK_LIMIT == ALLOCSET_SEPARATE_THRESHOLD,
"ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
/*
* Determine the maximum size that a chunk can be before we allocate an
* entire AllocBlock dedicated for that chunk. We set the absolute limit
* of that size as ALLOC_CHUNK_LIMIT but we reduce it further so that we

View file

@ -924,25 +924,35 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
*
* If the "condition" (a compile-time-constant expression) evaluates to false,
* throw a compile error using the "errmessage" (a string literal).
*
*/
/*
* We require C11 and C++11, so static_assert() is expected to be there.
* StaticAssertDecl() was previously used for portability, but it's now just a
* plain wrapper and doesn't need to be used in new code. static_assert() is
* a "declaration", and so it must be placed where for example a variable
* declaration would be valid. As long as we compile with
* -Wno-declaration-after-statement, that also means it cannot be placed after
* statements in a function. Macros StaticAssertStmt() and StaticAssertExpr()
* make it safe to use as a statement or in an expression, respectively.
* statements in a function.
*/
#define StaticAssertDecl(condition, errmessage) \
static_assert(condition, errmessage)
/*
* StaticAssertStmt() was previously used to make static assertions work as a
* statement, but its use is now deprecated.
*/
#define StaticAssertStmt(condition, errmessage) \
do { static_assert(condition, errmessage); } while(0)
/*
* StaticAssertExpr() is for use in an expression.
*
* For compilers without GCC statement expressions, we fall back on a kluge
* that assumes the compiler will complain about a negative width for a struct
* bit-field. This will not include a helpful error message, but it beats not
* getting an error at all.
*/
#define StaticAssertDecl(condition, errmessage) \
static_assert(condition, errmessage)
#define StaticAssertStmt(condition, errmessage) \
do { static_assert(condition, errmessage); } while(0)
#ifdef HAVE_STATEMENT_EXPRESSIONS
#define StaticAssertExpr(condition, errmessage) \
((void) ({ static_assert(condition, errmessage); true; }))