[glib/c99-int-types] Use C99 integer types where appropriate



commit 5e516be77709c1b4191b0cf0ef42812e412373f2
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Thu Dec 19 15:45:32 2019 +0000

    Use C99 integer types where appropriate
    
    GLib depends on various parts of a valid C99 toolchain, so it's time to
    use C99 integer types wherever possible, instead of doing configure-time
    discovery like it's 1997.
    
    So:
    
      gint8   → int8_t      guint8   → uint8_t
      gint16  → int16_t     guint16  → uint16_t
      gint32  → int32_t     guint32  → uint32_t
      gint64  → int64_t     guint64  → uint64_t
                            gsize    → size_t
      gintptr → intptr_t    guintptr → uintptr_t
    
    There are some side effects on switching to C99:
    
     - the G_*_MODIFIER macros do not really make any more sense, and should
     be deprecated and replaced by an empty string
     - the G_*_FORMAT macros are marked for use with both printf() and
     scanf(), except that's not really true at all; C99 defines format
     macros for print() and scanf() separately, and GLib should do the
     same. The old macros should be deprecated, but if we want to be evil
     about it, we could alias them with the PRINTF_FORMAT, as it's likely
     their more dominant use
    
    In general, there shouldn't be any ABI changes, unless the toolchain in
    use is not conformant to C99.
    
    Closes #1484

 glib/glibconfig.h.in |  47 ++++++++++++++------
 meson.build          | 120 ++++++++++++++++-----------------------------------
 tests/type-test.c    |  17 ++++++--
 3 files changed, 83 insertions(+), 101 deletions(-)
---
diff --git a/glib/glibconfig.h.in b/glib/glibconfig.h.in
index 7ef8c481d..13c5ca93c 100644
--- a/glib/glibconfig.h.in
+++ b/glib/glibconfig.h.in
@@ -10,6 +10,8 @@
 
 #include <limits.h>
 #include <float.h>
+#include <stdint.h>
+#include <inttypes.h>
 #mesondefine GLIB_HAVE_ALLOCA_H
 
 /* Specifies that GLib's g_print*() functions wrap the
@@ -37,37 +39,54 @@ G_BEGIN_DECLS
 #define G_MAXLONG      LONG_MAX
 #define G_MAXULONG     ULONG_MAX
 
-typedef signed char gint8;
-typedef unsigned char guint8;
+typedef int8_t gint8;
+typedef uint8_t guint8;
 
-typedef signed @gint16@ gint16;
-typedef unsigned @gint16@ guint16;
+#define G_GINT8_PRINTF_FORMAT PRId8
+#define G_GINT8_SCANF_FORMAT SCNd8
+#define G_GUINT8_PRINTF_FORMAT PRIu8
+#define G_GUINT8_SCANF_FORMAT SCNu8
+
+typedef int16_t gint16;
+typedef uint16_t guint16;
 
 #define G_GINT16_MODIFIER @gint16_modifier@
 #define G_GINT16_FORMAT @gint16_format@
 #define G_GUINT16_FORMAT @guint16_format@
 
+#define G_GINT16_PRINTF_FORMAT PRId16
+#define G_GINT16_SCANF_FORMAT SCNd16
+#define G_GUINT16_PRINTF_FORMAT PRIu16
+#define G_GUINT16_SCANF_FORMAT SCNu16
 
-typedef signed @gint32@ gint32;
-typedef unsigned @gint32@ guint32;
+typedef int32_t gint32;
+typedef uint32_t guint32;
 
 #define G_GINT32_MODIFIER @gint32_modifier@
 #define G_GINT32_FORMAT @gint32_format@
 #define G_GUINT32_FORMAT @guint32_format@
 
+#define G_GINT32_PRINTF_FORMAT PRId32
+#define G_GINT32_SCANF_FORMAT SCNd32
+#define G_GUINT32_PRINTF_FORMAT PRIu32
+#define G_GUINT32_SCANF_FORMAT SCNu32
 
 #define G_HAVE_GINT64 1          /* deprecated, always true */
 
-@glib_extension@typedef signed @gint64@ gint64;
-@glib_extension@typedef unsigned @gint64@ guint64;
+typedef int64_t gint64;
+typedef uint64_t guint64;
 
-#define G_GINT64_CONSTANT(val) @gint64_constant@
-#define G_GUINT64_CONSTANT(val)        @guint64_constant@
+#define G_GINT64_CONSTANT(val) INT64_C(val)
+#define G_GUINT64_CONSTANT(val)        UINT64_C(val)
 
 #define G_GINT64_MODIFIER @gint64_modifier@
 #define G_GINT64_FORMAT @gint64_format@
 #define G_GUINT64_FORMAT @guint64_format@
 
+#define G_GINT64_PRINTF_FORMAT PRId64
+#define G_GINT64_SCANF_FORMAT SCNd64
+#define G_GUINT64_PRINTF_FORMAT PRIu64
+#define G_GUINT64_SCANF_FORMAT SCNu64
 
 #define GLIB_SIZEOF_VOID_P @glib_void_p@
 #define GLIB_SIZEOF_LONG   @glib_long@
@@ -75,13 +94,13 @@ typedef unsigned @gint32@ guint32;
 #define GLIB_SIZEOF_SSIZE_T @glib_ssize_t@
 
 typedef signed @glib_size_type_define@ gssize;
-typedef unsigned @glib_size_type_define@ gsize;
+typedef size_t gsize;
 #define G_GSIZE_MODIFIER @gsize_modifier@
 #define G_GSSIZE_MODIFIER @gssize_modifier@
 #define G_GSIZE_FORMAT @gsize_format@
 #define G_GSSIZE_FORMAT @gssize_format@
 
-#define G_MAXSIZE      G_MAXU@glib_msize_type@
+#define G_MAXSIZE      SIZE_MAX
 #define G_MINSSIZE     G_MIN@glib_msize_type@
 #define G_MAXSSIZE     G_MAX@glib_msize_type@
 
@@ -101,8 +120,8 @@ typedef gint64 goffset;
 #define GINT_TO_POINTER(i)     ((gpointer) @glib_gpi_cast@ (i))
 #define GUINT_TO_POINTER(u)    ((gpointer) @glib_gpui_cast@ (u))
 
-typedef signed @glib_intptr_type_define@ gintptr;
-typedef unsigned @glib_intptr_type_define@ guintptr;
+typedef intptr_t gintptr;
+typedef uintptr_t guintptr;
 
 #define G_GINTPTR_MODIFIER      @gintptr_modifier@
 #define G_GINTPTR_FORMAT        @gintptr_format@
diff --git a/meson.build b/meson.build
index bb6040558..fd9d9d326 100644
--- a/meson.build
+++ b/meson.build
@@ -1174,6 +1174,7 @@ if long_long_size == long_size
                       return 1;
                     }''', name : 'int64_t is long')
     int64_t_typedef = 'long'
+    int64_m = 'l'
   elif cc.compiles('''#if defined(_AIX) && !defined(__GNUC__)
                       #pragma options langlvl=stdc99
                       #endif
@@ -1186,10 +1187,10 @@ if long_long_size == long_size
                         return 1;
                       }''', name : 'int64_t is long long')
     int64_t_typedef = 'long long'
+    int64_m = 'll'
   endif
 endif
 
-int64_m = 'll'
 char_align = cc.alignment('char')
 short_align = cc.alignment('short')
 int_align = cc.alignment('int')
@@ -1212,89 +1213,45 @@ glib_conf.set('SIZEOF_SSIZE_T', ssizet_size)
 glib_conf.set('SIZEOF_VOID_P', voidp_size)
 glib_conf.set('SIZEOF_WCHAR_T', cc.sizeof('wchar_t', prefix: '#include <stddef.h>'))
 
-if short_size == 2
-  gint16 = 'short'
-  gint16_modifier='h'
-  gint16_format='hi'
-  guint16_format='hu'
-elif int_size == 2
-  gint16 = 'int'
-  gint16_modifier=''
-  gint16_format='i'
-  guint16_format='u'
-else
-  error('Compiler provides no native 16-bit integer type')
+if not cc.has_header('stdint.h')
+  error('Missing stdint.h; GLib requires a C99 toolchain')
 endif
-glibconfig_conf.set('gint16', gint16)
+
+native_int_types = [
+  [ 'int16_t', '16 bit' ],
+  [ 'int32_t', '32 bit' ],
+  [ 'int64_t', '64 bit' ],
+]
+
+foreach type: native_int_types
+  if not cc.has_header_symbol('stdint.h', type[0])
+    error('Missing native @0@ type'.format(type[1]))
+  endif
+endforeach
+
+# Legacy symbols for sized integers
+gint16_modifier = ''
+gint16_format = 'PRId16'
+guint16_format = 'PRIu16'
 glibconfig_conf.set_quoted('gint16_modifier', gint16_modifier)
-glibconfig_conf.set_quoted('gint16_format', gint16_format)
-glibconfig_conf.set_quoted('guint16_format', guint16_format)
-
-if short_size == 4
-  gint32 = 'short'
-  gint32_modifier='h'
-  gint32_format='hi'
-  guint32_format='hu'
-  guint32_align = short_align
-elif int_size == 4
-  gint32 = 'int'
-  gint32_modifier=''
-  gint32_format='i'
-  guint32_format='u'
-  guint32_align = int_align
-elif long_size == 4
-  gint32 = 'long'
-  gint32_modifier='l'
-  gint32_format='li'
-  guint32_format='lu'
-  guint32_align = long_align
-else
-  error('Compiler provides no native 32-bit integer type')
-endif
-glibconfig_conf.set('gint32', gint32)
+glibconfig_conf.set('gint16_format', gint16_format)
+glibconfig_conf.set('guint16_format', guint16_format)
+
+gint32_modifier = ''
+gint32_format = 'PRId32'
+guint32_format = 'PRIu32'
 glibconfig_conf.set_quoted('gint32_modifier', gint32_modifier)
-glibconfig_conf.set_quoted('gint32_format', gint32_format)
-glibconfig_conf.set_quoted('guint32_format', guint32_format)
-glib_conf.set('ALIGNOF_GUINT32', guint32_align)
-
-if int_size == 8
-  gint64 = 'int'
-  gint64_modifier=''
-  gint64_format='i'
-  guint64_format='u'
-  glib_extension=''
-  gint64_constant='(val)'
-  guint64_constant='(val)'
-  guint64_align = int_align
-elif long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long')
-  gint64 = 'long'
-  glib_extension=''
-  gint64_modifier='l'
-  gint64_format='li'
-  guint64_format='lu'
-  gint64_constant='(val##L)'
-  guint64_constant='(val##UL)'
-  guint64_align = long_align
-elif long_long_size == 8 and (long_long_size != long_size or int64_t_typedef == 'long long')
-  gint64 = 'long long'
-  glib_extension='G_GNUC_EXTENSION '
-  gint64_modifier=int64_m
-  gint64_format=int64_m + 'i'
-  guint64_format=int64_m + 'u'
-  gint64_constant='(G_GNUC_EXTENSION (val##LL))'
-  guint64_constant='(G_GNUC_EXTENSION (val##ULL))'
-  guint64_align = long_long_align
-else
-  error('Compiler provides no native 64-bit integer type')
-endif
-glibconfig_conf.set('glib_extension', glib_extension)
-glibconfig_conf.set('gint64', gint64)
+glibconfig_conf.set('gint32_format', gint32_format)
+glibconfig_conf.set('guint32_format', guint32_format)
+glib_conf.set('ALIGNOF_GUINT32', cc.alignment('uint32_t', prefix: '#include <stdint.h>'))
+
+gint64_modifier = int64_m
+gint64_format = 'PRId64'
+guint64_format = 'PRIu64'
 glibconfig_conf.set_quoted('gint64_modifier', gint64_modifier)
-glibconfig_conf.set_quoted('gint64_format', gint64_format)
-glibconfig_conf.set_quoted('guint64_format', guint64_format)
-glibconfig_conf.set('gint64_constant', gint64_constant)
-glibconfig_conf.set('guint64_constant', guint64_constant)
-glib_conf.set('ALIGNOF_GUINT64', guint64_align)
+glibconfig_conf.set('gint64_format', gint64_format)
+glibconfig_conf.set('guint64_format', guint64_format)
+glib_conf.set('ALIGNOF_GUINT64', cc.alignment('uint64_t', prefix: '#include <stdint.h>'))
 
 if host_system == 'windows'
   glibconfig_conf.set('g_pid_type', 'void*')
@@ -1405,21 +1362,18 @@ else
 endif
 
 if voidp_size == int_size
-  glibconfig_conf.set('glib_intptr_type_define', 'int')
   glibconfig_conf.set_quoted('gintptr_modifier', '')
   glibconfig_conf.set_quoted('gintptr_format', 'i')
   glibconfig_conf.set_quoted('guintptr_format', 'u')
   glibconfig_conf.set('glib_gpi_cast', '(gint)')
   glibconfig_conf.set('glib_gpui_cast', '(guint)')
 elif voidp_size == long_size
-  glibconfig_conf.set('glib_intptr_type_define', 'long')
   glibconfig_conf.set_quoted('gintptr_modifier', 'l')
   glibconfig_conf.set_quoted('gintptr_format', 'li')
   glibconfig_conf.set_quoted('guintptr_format', 'lu')
   glibconfig_conf.set('glib_gpi_cast', '(glong)')
   glibconfig_conf.set('glib_gpui_cast', '(gulong)')
 elif voidp_size == long_long_size
-  glibconfig_conf.set('glib_intptr_type_define', 'long long')
   glibconfig_conf.set_quoted('gintptr_modifier', int64_m)
   glibconfig_conf.set_quoted('gintptr_format', int64_m + 'i')
   glibconfig_conf.set_quoted('guintptr_format', int64_m + 'u')
diff --git a/tests/type-test.c b/tests/type-test.c
index dceccdd9f..20eaf196c 100644
--- a/tests/type-test.c
+++ b/tests/type-test.c
@@ -106,10 +106,19 @@ main (int   argc,
   gi32t1 = -0x3AFAFAFA;
   gu32t1 = 0xFAFAFAFA; 
 
-#define FORMAT "%" G_GINT16_FORMAT " %" G_GINT32_FORMAT \
-               " %" G_GUINT16_FORMAT " %" G_GUINT32_FORMAT "\n"
-  string = g_strdup_printf (FORMAT, gi16t1, gi32t1, gu16t1, gu32t1);
-  sscanf (string, FORMAT, &gi16t2, &gi32t2, &gu16t2, &gu32t2);
+#define PRINTF_FORMAT "%" G_GINT16_FORMAT \
+                      " %" G_GINT32_FORMAT \
+                      " %" G_GUINT16_FORMAT \
+                      " %" G_GUINT32_FORMAT \
+                      "\n"
+  string = g_strdup_printf (PRINTF_FORMAT, gi16t1, gi32t1, gu16t1, gu32t1);
+
+#define SCANF_FORMAT "%" G_GINT16_SCANF_FORMAT \
+                     " %" G_GINT32_SCANF_FORMAT \
+                     " %" G_GUINT16_SCANF_FORMAT \
+                     " %" G_GUINT32_SCANF_FORMAT \
+                     "\n"
+  sscanf (string, SCANF_FORMAT, &gi16t2, &gi32t2, &gu16t2, &gu32t2);
   g_free (string);
   g_assert (gi16t1 == gi16t2);
   g_assert (gi32t1 == gi32t2);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]