glib-init: Statically assert that types have appropriate signedness

Some of these are properties of a Standard C or POSIX platform that
are true by definition and checked for completeness (for example intptr_t
is defined to be signed, and uintptr_t unsigned), while others are
checking that GLib's type detection has been done correctly.

Signed-off-by: Simon McVittie <smcv@debian.org>
This commit is contained in:
Simon McVittie 2024-05-15 12:56:54 +01:00 committed by Philip Withnall
parent a0ed94a11d
commit 7efb96d29b
2 changed files with 39 additions and 0 deletions

View File

@ -82,6 +82,11 @@ G_STATIC_ASSERT (G_ALIGNOF (TestInt) == G_ALIGNOF (int));
G_STATIC_ASSERT (sizeof (gchar) == 1);
G_STATIC_ASSERT (sizeof (guchar) == 1);
/* It is platform-dependent whether gchar is signed or unsigned, so there
* is no assertion here for it */
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guchar) == 0);
G_STATIC_ASSERT (sizeof (gint8) * CHAR_BIT == 8);
G_STATIC_ASSERT (sizeof (guint8) * CHAR_BIT == 8);
G_STATIC_ASSERT (sizeof (gint16) * CHAR_BIT == 16);
@ -100,12 +105,16 @@ G_STATIC_ASSERT (G_MINSHORT == SHRT_MIN);
G_STATIC_ASSERT (G_MAXSHORT == SHRT_MAX);
G_STATIC_ASSERT (sizeof (unsigned short) == sizeof (gushort));
G_STATIC_ASSERT (G_MAXUSHORT == USHRT_MAX);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gshort) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gushort) == 0);
G_STATIC_ASSERT (sizeof (int) == sizeof (gint));
G_STATIC_ASSERT (G_MININT == INT_MIN);
G_STATIC_ASSERT (G_MAXINT == INT_MAX);
G_STATIC_ASSERT (sizeof (unsigned int) == sizeof (guint));
G_STATIC_ASSERT (G_MAXUINT == UINT_MAX);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint) == 0);
G_STATIC_ASSERT (sizeof (long) == GLIB_SIZEOF_LONG);
G_STATIC_ASSERT (sizeof (long) == sizeof (glong));
@ -113,6 +122,8 @@ G_STATIC_ASSERT (G_MINLONG == LONG_MIN);
G_STATIC_ASSERT (G_MAXLONG == LONG_MAX);
G_STATIC_ASSERT (sizeof (unsigned long) == sizeof (gulong));
G_STATIC_ASSERT (G_MAXULONG == ULONG_MAX);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (glong) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gulong) == 0);
G_STATIC_ASSERT (G_HAVE_GINT64 == 1);
@ -132,6 +143,10 @@ G_STATIC_ASSERT (G_ALIGNOF (gssize) == G_ALIGNOF (size_t));
* However, we do not assume that GPOINTER_TO_SIZE can store an arbitrary
* pointer in a gsize (known to be false on CHERI). */
G_STATIC_ASSERT (sizeof (size_t) <= sizeof (void *));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (size_t) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gsize) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gssize) == 1);
/* Standard C does not guarantee that size_t is the same as uintptr_t,
* but GLib currently assumes they are the same: see
* <https://gitlab.gnome.org/GNOME/glib/-/issues/2842>.
@ -144,10 +159,13 @@ G_STATIC_ASSERT (sizeof (size_t) <= sizeof (void *));
G_STATIC_ASSERT (sizeof (size_t) == sizeof (uintptr_t));
G_STATIC_ASSERT (G_ALIGNOF (size_t) == G_ALIGNOF (uintptr_t));
#endif
/* goffset is always 64-bit, even if off_t is only 32-bit
* (compiling without large-file-support on 32-bit) */
G_STATIC_ASSERT (sizeof (goffset) == sizeof (gint64));
G_STATIC_ASSERT (G_ALIGNOF (goffset) == G_ALIGNOF (gint64));
/* goffset is always signed */
G_STATIC_ASSERT (G_SIGNEDNESS_OF (goffset) == 1);
G_STATIC_ASSERT (sizeof (gfloat) == sizeof (float));
G_STATIC_ASSERT (G_ALIGNOF (gfloat) == G_ALIGNOF (float));
@ -158,26 +176,44 @@ G_STATIC_ASSERT (sizeof (gintptr) == sizeof (intptr_t));
G_STATIC_ASSERT (sizeof (guintptr) == sizeof (uintptr_t));
G_STATIC_ASSERT (G_ALIGNOF (gintptr) == G_ALIGNOF (intptr_t));
G_STATIC_ASSERT (G_ALIGNOF (guintptr) == G_ALIGNOF (uintptr_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gintptr) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guintptr) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (intptr_t) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uintptr_t) == 0);
G_STATIC_ASSERT (sizeof (gint8) == sizeof (int8_t));
G_STATIC_ASSERT (sizeof (guint8) == sizeof (uint8_t));
G_STATIC_ASSERT (G_ALIGNOF (gint8) == G_ALIGNOF (int8_t));
G_STATIC_ASSERT (G_ALIGNOF (guint8) == G_ALIGNOF (uint8_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint8) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint8) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int8_t) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint8_t) == 0);
G_STATIC_ASSERT (sizeof (gint16) == sizeof (int16_t));
G_STATIC_ASSERT (sizeof (guint16) == sizeof (uint16_t));
G_STATIC_ASSERT (G_ALIGNOF (gint16) == G_ALIGNOF (int16_t));
G_STATIC_ASSERT (G_ALIGNOF (guint16) == G_ALIGNOF (uint16_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int16_t) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint16_t) == 0);
G_STATIC_ASSERT (sizeof (gint32) == sizeof (int32_t));
G_STATIC_ASSERT (sizeof (guint32) == sizeof (uint32_t));
G_STATIC_ASSERT (G_ALIGNOF (gint32) == G_ALIGNOF (int32_t));
G_STATIC_ASSERT (G_ALIGNOF (guint32) == G_ALIGNOF (uint32_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint32) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint32) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int32_t) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint32_t) == 0);
G_STATIC_ASSERT (sizeof (gint64) == sizeof (int64_t));
G_STATIC_ASSERT (sizeof (guint64) == sizeof (uint64_t));
G_STATIC_ASSERT (G_ALIGNOF (gint64) == G_ALIGNOF (int64_t));
G_STATIC_ASSERT (G_ALIGNOF (guint64) == G_ALIGNOF (uint64_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (gint64) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (guint64) == 0);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (int64_t) == 1);
G_STATIC_ASSERT (G_SIGNEDNESS_OF (uint64_t) == 0);
/**
* g_mem_gc_friendly:

View File

@ -38,6 +38,7 @@
#include "config.h"
#include "glib-private.h"
#include "glib-unix.h"
#include "glib-unixprivate.h"
#include "gmain-internal.h"
@ -66,9 +67,11 @@
G_STATIC_ASSERT (sizeof (ssize_t) == GLIB_SIZEOF_SSIZE_T);
G_STATIC_ASSERT (G_ALIGNOF (gssize) == G_ALIGNOF (ssize_t));
G_STATIC_ASSERT (G_SIGNEDNESS_OF (ssize_t) == 1);
G_STATIC_ASSERT (sizeof (GPid) == sizeof (pid_t));
G_STATIC_ASSERT (G_ALIGNOF (GPid) == G_ALIGNOF (pid_t));
/* It's platform-dependent whether pid_t is signed, so no assertion */
/* If this assertion fails, then the ABI of g_unix_open_pipe() would be
* ambiguous on this platform.