[glib] glib-init: statically assert that "small" enums are all int-sized
- From: Simon McVittie <smcv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] glib-init: statically assert that "small" enums are all int-sized
- Date: Tue, 22 Nov 2016 19:28:35 +0000 (UTC)
commit 52276300779f5f540f5b19bc0c9308a069eeb401
Author: Simon McVittie <simon mcvittie collabora co uk>
Date: Thu May 29 12:20:24 2014 +0100
glib-init: statically assert that "small" enums are all int-sized
ISO C allows compilers to make enums smaller than int if their
enumerated values would all fit in the range of a smaller type.
In practice, I suspect that in relevant compilers, all enums whose
values fit in the range INT32_MIN to INT32_MAX (inclusive) are the same
size as int. ISO C allows compiler to break that assumption, but those
that do would break code that works fine in other compilers, making the
compiler look bad, for no significant benefit. I conjecture that such
compilers are not popular.
Let's statically assert that my assumption holds. If all goes well,
GLib will continue to compile on every relevant platform; if it
fails to compile on some platform as a result of this change, then
there are probably a lot of naive uses of enums that need auditing
for this assumption.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=730932
Signed-off-by: Simon McVittie <simon mcvittie collabora co uk>
Reviewed-by: Allison Lortie
glib/glib-init.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
---
diff --git a/glib/glib-init.c b/glib/glib-init.c
index 5a5c215..07ca239 100644
--- a/glib/glib-init.c
+++ b/glib/glib-init.c
@@ -45,6 +45,29 @@ G_STATIC_ASSERT (_g_alignof (gpointer) == _g_alignof (GFunc));
G_STATIC_ASSERT (sizeof (GFunc) == sizeof (GCompareDataFunc));
G_STATIC_ASSERT (_g_alignof (GFunc) == _g_alignof (GCompareDataFunc));
+/* We assume that "small" enums (those where all values fit in INT32_MIN
+ * to INT32_MAX) are exactly int-sized. In particular, we assume that if
+ * an enum has no members that exceed the range of char/short, the
+ * compiler will make it int-sized anyway, so adding a member later that
+ * *does* exceed the range of char/short is not an ABI break. */
+typedef enum {
+ TEST_CHAR_0 = 0
+} TestChar;
+typedef enum {
+ TEST_SHORT_0 = 0,
+ TEST_SHORT_256 = 256
+} TestShort;
+typedef enum {
+ TEST_INT32_MIN = G_MININT32,
+ TEST_INT32_MAX = G_MAXINT32
+} TestInt;
+G_STATIC_ASSERT (sizeof (TestChar) == sizeof (int));
+G_STATIC_ASSERT (sizeof (TestShort) == sizeof (int));
+G_STATIC_ASSERT (sizeof (TestInt) == sizeof (int));
+G_STATIC_ASSERT (_g_alignof (TestChar) == _g_alignof (int));
+G_STATIC_ASSERT (_g_alignof (TestShort) == _g_alignof (int));
+G_STATIC_ASSERT (_g_alignof (TestInt) == _g_alignof (int));
+
/**
* g_mem_gc_friendly:
*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]