return true;
}
- /*
- * Check all-zeroes case. Luckily BLCKSZ is guaranteed to always be a
- * multiple of size_t - and it's much faster to compare memory using the
- * native word size.
- */
- StaticAssertStmt(BLCKSZ == (BLCKSZ / sizeof(size_t)) * sizeof(size_t),
- "BLCKSZ has to be a multiple of sizeof(size_t)");
-
+ /* Check all-zeroes case */
all_zeroes = true;
pagebytes = (size_t *) page;
for (i = 0; i < (BLCKSZ / sizeof(size_t)); i++)
"advisory"
};
+StaticAssertDecl(lengthof(LockTagTypeNames) == (LOCKTAG_ADVISORY + 1),
+ "array length mismatch");
+
/* This must match enum PredicateLockTargetType (predicate_internals.h) */
static const char *const PredicateLockTagTypeNames[] = {
"relation",
"tuple"
};
+StaticAssertDecl(lengthof(PredicateLockTagTypeNames) == (PREDLOCKTAG_TUPLE + 1),
+ "array length mismatch");
+
/* Working status for pg_lock_status */
typedef struct
{
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(bytea_output_options) == (BYTEA_OUTPUT_HEX + 2),
+ "array length mismatch");
+
/*
* We have different sets for client and server message level options because
* they sort slightly different (see "log" level), and because "fatal"/"panic"
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(intervalstyle_options) == (INTSTYLE_ISO_8601 + 2),
+ "array length mismatch");
+
static const struct config_enum_entry log_error_verbosity_options[] = {
{"terse", PGERROR_TERSE, false},
{"default", PGERROR_DEFAULT, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(log_error_verbosity_options) == (PGERROR_VERBOSE + 2),
+ "array length mismatch");
+
static const struct config_enum_entry log_statement_options[] = {
{"none", LOGSTMT_NONE, false},
{"ddl", LOGSTMT_DDL, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(log_statement_options) == (LOGSTMT_ALL + 2),
+ "array length mismatch");
+
static const struct config_enum_entry isolation_level_options[] = {
{"serializable", XACT_SERIALIZABLE, false},
{"repeatable read", XACT_REPEATABLE_READ, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(session_replication_role_options) == (SESSION_REPLICATION_ROLE_LOCAL + 2),
+ "array length mismatch");
+
static const struct config_enum_entry syslog_facility_options[] = {
#ifdef HAVE_SYSLOG
{"local0", LOG_LOCAL0, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(track_function_options) == (TRACK_FUNC_ALL + 2),
+ "array length mismatch");
+
static const struct config_enum_entry xmlbinary_options[] = {
{"base64", XMLBINARY_BASE64, false},
{"hex", XMLBINARY_HEX, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(xmlbinary_options) == (XMLBINARY_HEX + 2),
+ "array length mismatch");
+
static const struct config_enum_entry xmloption_options[] = {
{"content", XMLOPTION_CONTENT, false},
{"document", XMLOPTION_DOCUMENT, false},
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(xmloption_options) == (XMLOPTION_CONTENT + 2),
+ "array length mismatch");
+
/*
* Although only "on", "off", and "safe_encoding" are documented, we
* accept all the likely variants of "on" and "off".
{NULL, 0, false}
};
+StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2),
+ "array length mismatch");
+
static struct config_enum_entry shared_memory_options[] = {
#ifndef WIN32
{"sysv", SHMEM_TYPE_SYSV, false},
/* PGC_USERSET */ "user"
};
+StaticAssertDecl(lengthof(GucContext_Names) == (PGC_USERSET + 1),
+ "array length mismatch");
+
/*
* Displayable names for source types (enum GucSource)
*
/* PGC_S_SESSION */ "session"
};
+StaticAssertDecl(lengthof(GucSource_Names) == (PGC_S_SESSION + 1),
+ "array length mismatch");
+
/*
* Displayable names for the groupings defined in enum config_group
*/
NULL
};
+StaticAssertDecl(lengthof(config_group_names) == (DEVELOPER_OPTIONS + 2),
+ "array length mismatch");
+
/*
* Displayable names for GUC variable types (enum config_type)
*
/* PGC_ENUM */ "enum"
};
+StaticAssertDecl(lengthof(config_type_names) == (PGC_ENUM + 1),
+ "array length mismatch");
+
/*
* Unit conversion tables.
*
38 /* DO_SUBSCRIPTION */
};
+StaticAssertDecl(lengthof(dbObjectTypePriority) == (DO_SUBSCRIPTION + 1),
+ "array length mismatch");
+
static DumpId preDataBoundId;
static DumpId postDataBoundId;
"init" /* INIT_FORKNUM */
};
+StaticAssertDecl(lengthof(forkNames) == (MAX_FORKNUM + 1),
+ "array length mismatch");
+
/*
* forkname_to_number - look up fork number by name
*
* throw a compile error using the "errmessage" (a string literal).
*
* gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
- * placement restrictions. These macros make it safe to use as a statement
- * or in an expression, respectively.
+ * placement restrictions. Macros StaticAssertStmt() and StaticAssertExpr()
+ * make it safe to use as a statement or in an expression, respectively.
+ * The macro StaticAssertDecl() is suitable for use at file scope (outside of
+ * any function).
*
* Otherwise 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
do { _Static_assert(condition, errmessage); } while(0)
#define StaticAssertExpr(condition, errmessage) \
((void) ({ StaticAssertStmt(condition, errmessage); true; }))
+#define StaticAssertDecl(condition, errmessage) \
+ _Static_assert(condition, errmessage)
#else /* !HAVE__STATIC_ASSERT */
#define StaticAssertStmt(condition, errmessage) \
((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
#define StaticAssertExpr(condition, errmessage) \
StaticAssertStmt(condition, errmessage)
+#define StaticAssertDecl(condition, errmessage) \
+ extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
#endif /* HAVE__STATIC_ASSERT */
#else /* C++ */
#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410
static_assert(condition, errmessage)
#define StaticAssertExpr(condition, errmessage) \
({ static_assert(condition, errmessage); })
-#else
+#define StaticAssertDecl(condition, errmessage) \
+ static_assert(condition, errmessage)
+#else /* !__cpp_static_assert */
#define StaticAssertStmt(condition, errmessage) \
do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0)
#define StaticAssertExpr(condition, errmessage) \
((void) ({ StaticAssertStmt(condition, errmessage); }))
-#endif
+#define StaticAssertDecl(condition, errmessage) \
+ extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
+#endif /* __cpp_static_assert */
#endif /* C++ */
((overwrite) ? PAI_OVERWRITE : 0) | \
((is_heap) ? PAI_IS_HEAP : 0))
+/*
+ * Check that BLCKSZ is a multiple of sizeof(size_t). In PageIsVerified(),
+ * it is much faster to check if a page is full of zeroes using the native
+ * word size. Note that this assertion is kept within a header to make
+ * sure that StaticAssertDecl() works across various combinations of
+ * platforms and compilers.
+ */
+StaticAssertDecl(BLCKSZ == ((BLCKSZ / sizeof(size_t)) * sizeof(size_t)),
+ "BLCKSZ has to be a multiple of sizeof(size_t)");
+
extern void PageInit(Page page, Size pageSize, Size specialSize);
extern bool PageIsVerified(Page page, BlockNumber blkno);
extern OffsetNumber PageAddItemExtended(Page page, Item item, Size size,