static_assert in c89 and c99

Message ID 54D40347.3020508@cs.ucla.edu
State Committed
Headers

Commit Message

Paul Eggert Feb. 5, 2015, 11:56 p.m. UTC
  On 02/05/2015 01:42 PM, Rich Felker wrote:
> glibc should check for 100*__GNUC__+__GNUC_MINOR__<406
> and use an alternate definition for _Static_assert in that case
This sounds right, and is like the similar situation for _Noreturn 
where' there's already a substitute in misc/sys/cdefs.h for older 
compilers.  Proposed patch attached.  (Not while we're frozen, of course.)

This patch borrows the implementation from Gnulib.  We've run into 
compilers that allow arrays of negative size (!) but none that allow 
bitfields of negative size, which is why we use bitfields.
  

Comments

Roland McGrath Feb. 6, 2015, 6:30 p.m. UTC | #1
That looks OK to me.
  
Paul Eggert Feb. 7, 2015, 10:53 p.m. UTC | #2
Roland McGrath wrote:
> That looks OK to me.

Thanks, I installed that into the master.

Actually, I installed something slightly more conservative, in that it does not 
define _Static_assert if C++.  This suffices to fix the problem, and should 
interoperate better with Gnulib's longstanding _Static_assert code for C++.
  

Patch

From f786ed830b83aa0edbca0b81478a7a70031594b4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 5 Feb 2015 15:52:20 -0800
Subject: [PATCH] Add ersatz _Static_assert on older hosts

* misc/sys/cdefs.h (_Static_assert): Define a substitute, if on a
pre-C11 pltform that is not known to support _Static_assert.
---
 ChangeLog        | 5 +++++
 assert/assert.h  | 1 -
 misc/sys/cdefs.h | 8 ++++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 50e8153..02ca85d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@ 
+2015-02-05  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* misc/sys/cdefs.h (_Static_assert): Define a substitute, if on a
+	pre-C11 platform that is not known to support _Static_assert.
+
 2015-01-31  David S. Miller  <davem@davemloft.net>
 
 	* sysdeps/sparc/sparc32/bits/atomic.h
diff --git a/assert/assert.h b/assert/assert.h
index ae77793..d04c58c 100644
--- a/assert/assert.h
+++ b/assert/assert.h
@@ -113,7 +113,6 @@  __END_DECLS
 
 
 #if defined __USE_ISOC11 && !defined __cplusplus
-/* Static assertion.  Requires support in the compiler.  */
 # undef static_assert
 # define static_assert _Static_assert
 #endif
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 09ee352..af3ebbf 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -399,6 +399,14 @@ 
 # endif
 #endif
 
+#if (!defined _Static_assert \
+     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+     && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
+# define _Static_assert(expr, diagnostic) \
+    extern int (*__Static_assert_function (void)) \
+      [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
+#endif
+
 #include <bits/wordsize.h>
 
 #if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
-- 
2.1.0