[glib] glib-init: statically assert that "small" enums are all int-sized



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]