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 680994 - STATIC_ASSERT in GDBusError docs don't have much utility
STATIC_ASSERT in GDBusError docs don't have much utility
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gdbus
unspecified
Other Linux
: Normal normal
: ---
Assigned To: David Zeuthen (not reading bugmail)
gtkdev
Depends on:
Blocks:
 
 
Reported: 2012-08-01 15:36 UTC by Jasper St. Pierre (not reading bugmail)
Modified: 2012-08-03 11:38 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jasper St. Pierre (not reading bugmail) 2012-08-01 15:36:38 UTC
From https://bugzilla.gnome.org/show_bug.cgi?id=678057#c95

http://developer.gnome.org/gio/unstable/gio-GDBusError.html#gio-GDBusError.description

The G_STATIC_ASSERT checks if the last item in the enum is the last item in the mapping:

enum {
    ONE,
    TWO,
    THREE,
};

GDBusErrorEntry mapping[] = {
    { ONE, "one" },
    { TWO, "two" },
    { THREE, "three" },
};

G_STATIC_ASSERT (G_NUM_ELEMENTS (mapping), THREE - 1);

This is clearly designed to prevent against new errors that are not in the mapping. But in the most common case, appending to the end of the enum, the static assert will not fire, as THREE hasn't shifted its place:

enum {
    ONE,
    TWO,
    THREE,
    FOUR,
};

GDBusErrorEntry mapping[] = {
    { ONE, "one" },
    { TWO, "two" },
    { THREE, "three" },
};

G_STATIC_ASSERT (G_NUM_ELEMENTS (mapping), THREE - 1);
Comment 1 David Zeuthen (not reading bugmail) 2012-08-01 15:43:42 UTC
How about this fix?

  *   FOO_BAR_ERROR_FAILED,
  *   FOO_BAR_ERROR_ANOTHER_ERROR,
  *   FOO_BAR_ERROR_SOME_THIRD_ERROR,
+ *   FOO_BAR_ERROR_N_ERRORS /*< skip *>/
  * } FooBarError;
  *
  * /<!-- -->* foo-bar-error.c: *<!-- -->/
@@ -83,11 +84,11 @@
  * foo_bar_error_quark (void)
  * {
  *   static volatile gsize quark_volatile = 0;
+ *   G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) == FOO_BAR_ERROR_N_ERRORS);
  *   g_dbus_error_register_error_domain ("foo-bar-error-quark",
  *                                       &quark_volatile,
  *                                       foo_bar_error_entries,
  *                                       G_N_ELEMENTS (foo_bar_error_entries));
- *   G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) - 1 == FOO_BAR_ERROR_SOME_THIRD_ERROR);
  *   return (GQuark) quark_volatile;
  * }
  * </programlisting></example>
Comment 2 David Zeuthen (not reading bugmail) 2012-08-01 15:59:15 UTC
After discussion on IRC, I ended up committing this fix

http://git.gnome.org/browse/glib/commit/?id=800ca21e555e5e9fe1f07a4a8473d6d24ada6301
Comment 3 Colin Walters 2012-08-02 02:45:43 UTC
Note you typically want to use 

#define FOO_N_ELEMENTS FOO_LAST_ELEMENT

instead of adding it to the enum itself; this helps avoid gcc warning you if it's missing from switch statements.
Comment 4 Allison Karlitskaya (desrt) 2012-08-03 11:37:42 UTC
I agree with the logic on the define, but I really prefer the N_ to the LAST_...
Comment 5 Allison Karlitskaya (desrt) 2012-08-03 11:38:13 UTC
(but I think the #define is only required if it's required.... which in this case it seems not to be.)