Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0d0aa5d

Browse files
committed
Provide some static-assertion functionality on all compilers.
On reflection (especially after noticing how many buildfarm critters have__builtin_types_compatible_p but not _Static_assert), it seems like weought to try a bit harder to make these macros do something everywhere.The initial cut at it would have been no help to code that is compiled onlyon platforms without _Static_assert, for instance; and in any case not allour contributors do their initial coding on the latest gcc version.Some googling about static assertions turns up quite a bit of prior artfor making it work in compilers that lack _Static_assert. The methodthat seems closest to our needs involves defining a struct with a bit-fieldthat has negative width if the assertion condition fails. There seems noreliable way to get the error message string to be output, but throwing acompile error with a confusing message is better than missing the problemaltogether.In the same spirit, if we don't have __builtin_types_compatible_p we can atleast insist that the variable have the same width as the type. This won'tcatch errors such as "wrong pointer type", but it's far better thannothing.In addition to changing the macro definitions, adjust acompile-time-constant Assert in contrib/hstore to use StaticAssertStmt,so we can get some buildfarm coverage on whether that macro behaves sanelyor not. There's surely more places that could be converted, but this isthe first one I came across.
1 parentea473fb commit0d0aa5d

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

‎contrib/hstore/hstore_compat.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
* etc. are compatible.
9595
*
9696
* If the above statement isn't true on some bizarre platform, we're
97-
* a bit hosed (seeAssert in hstoreValidOldFormat).
97+
* a bit hosed (seeStaticAssertStmt in hstoreValidOldFormat).
9898
*/
9999
typedefstruct
100100
{
@@ -180,7 +180,8 @@ hstoreValidOldFormat(HStore *hs)
180180
return0;
181181

182182
/* New format uses an HEntry for key and another for value */
183-
Assert(sizeof(HOldEntry)== (2*sizeof(HEntry)));
183+
StaticAssertStmt(sizeof(HOldEntry)==2*sizeof(HEntry),
184+
"old hstore format is not upward-compatible");
184185

185186
if (count==0)
186187
return2;

‎src/include/c.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -690,23 +690,29 @@ typedef NameData *Name;
690690

691691

692692
/*
693-
* Macros to support compile-time assertion checks, if the compiler has them.
693+
* Macros to support compile-time assertion checks.
694694
*
695695
* If the "condition" (a compile-time-constant expression) evaluates to false,
696696
* throw a compile error using the "errmessage" (a string literal).
697697
*
698-
* gcc 4.6 and up supports _Static_assert(), butit has bizarre syntactic
698+
* gcc 4.6 and up supports _Static_assert(), butthere are bizarre syntactic
699699
* placement restrictions. These macros make it safe to use as a statement
700700
* or in an expression, respectively.
701+
*
702+
* Otherwise we fall back on a kluge that assumes the compiler will complain
703+
* about a negative width for a struct bit-field. This will not include a
704+
* helpful error message, but it beats not getting an error at all.
701705
*/
702706
#ifdefHAVE__STATIC_ASSERT
703707
#defineStaticAssertStmt(condition,errmessage) \
704708
do { _Static_assert(condition, errmessage); } while(0)
705709
#defineStaticAssertExpr(condition,errmessage) \
706710
({ StaticAssertStmt(condition, errmessage); true; })
707711
#else/* !HAVE__STATIC_ASSERT */
708-
#defineStaticAssertStmt(condition,errmessage)
709-
#defineStaticAssertExpr(condition,errmessage) ((void) true)
712+
#defineStaticAssertStmt(condition,errmessage) \
713+
((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
714+
#defineStaticAssertExpr(condition,errmessage) \
715+
StaticAssertStmt(condition, errmessage)
710716
#endif/* HAVE__STATIC_ASSERT */
711717

712718

@@ -716,6 +722,10 @@ typedef NameData *Name;
716722
* AssertVariableIsOfType() can be used as a statement.
717723
* AssertVariableIsOfTypeMacro() is intended for use in macros, eg
718724
*#define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
725+
*
726+
* If we don't have __builtin_types_compatible_p, we can still assert that
727+
* the types have the same size. This is far from ideal (especially on 32-bit
728+
* platforms) but it provides at least some coverage.
719729
*/
720730
#ifdefHAVE__BUILTIN_TYPES_COMPATIBLE_P
721731
#defineAssertVariableIsOfType(varname,typename) \
@@ -725,8 +735,12 @@ typedef NameData *Name;
725735
StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
726736
CppAsString(varname) " does not have type " CppAsString(typename))
727737
#else/* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
728-
#defineAssertVariableIsOfType(varname,typename)
729-
#defineAssertVariableIsOfTypeMacro(varname,typename) ((void) true)
738+
#defineAssertVariableIsOfType(varname,typename) \
739+
StaticAssertStmt(sizeof(varname) == sizeof(typename), \
740+
CppAsString(varname) " does not have type " CppAsString(typename))
741+
#defineAssertVariableIsOfTypeMacro(varname,typename) \
742+
StaticAssertExpr(sizeof(varname) == sizeof(typename), \
743+
CppAsString(varname) " does not have type " CppAsString(typename))
730744
#endif/* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
731745

732746

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp