After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 581023 - support GCC transparent unions
support GCC transparent unions
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2009-05-01 16:12 UTC by Allison Karlitskaya (desrt)
Modified: 2018-05-24 11:50 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Allison Karlitskaya (desrt) 2009-05-01 16:12:59 UTC
#include <glib.h>

/*
one of my biggest pet peeves about C is the mess that it is to accept a read-only array of strings to a function.  you can write:

  void func (const gchar * const *array);

but then if you try to use it with a (gchar **) you fail due to a pointer incompatibility error.

GCC has this "transparent union" feature that lets functions take, as arguments, one pointer type or another.  we could have something like this:
*/

#ifdef __GNUC__
#define G_UNION_POINTER(one,two) \
  union { one *left; two *right; } __attribute__ ((__transparent_union__))
#define G_UNION_POINTER_LEFT(ptr)  ptr.left
#define G_UNION_POINTER_RIGHT(ptr)  ptr.left

/*
in the non-GCC case we can gracefully degrade by abandoning safety and using gpointer:
*/

#else
#define G_UNION_POINTER(one,two) gpointer
#define G_UNION_POINTER_LEFT(ptr)   (ptr)
#define G_UNION_POINTER_RIGHT(ptr)   (ptr)
#endif

/*
the idea here would be that
  a) most developers are using GCC
  b) even if someone isn't, someone using GCC will later catch the problem
  c) it compiles for everyone


then we can write functions like this:
*/

static int
strv_length (G_UNION_POINTER (const gchar * const, gchar *) strv)
{
  const gchar * const *array = G_UNION_POINTER_LEFT (strv);
  int i;

  for (i = 0; array[i]; i++);

  return i;
}

//maybe we should have special types for arrays of strings:

typedef G_UNION_POINTER (gchar *, const gchar * const) gconststrv;
typedef gchar **gstrv;
#define G_CONSTSTRV_TO_STRV G_UNION_POINTER_LEFT

//so we could write like:

static int
strv_length2 (gconststrv strv)
{
  gstrv array = G_CONSTSTRV_TO_STRV (strv);
  int i;

  for (i = 0; array[i]; i++);

  return i;
}

/*
then you can use these functions like so:
*/

int
main (void)
{
  const gchar *my_array[] = { "foo", "bar", NULL };

  strv_length (g_strsplit ("", "", 0));
  strv_length (my_array);

  strv_length2 (g_strsplit ("", "", 0));
  strv_length2 (my_array);

  return 0;
}
Comment 1 GNOME Infrastructure Team 2018-05-24 11:50:56 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/216.