[glib/wip/gvariant-kdbus: 1/17] macros: add side-effecting variants of asserts



commit 39ca9d33832ccb71ca3a330faf10dd6a56dea0f1
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Dec 1 16:33:32 2014 -0500

    macros: add side-effecting variants of asserts
    
    Add g_assert_se(), g_return_if_fail_se() and g_return_val_if_fail_se()
    as variants of the existing macros that are guaranteed to evaluate side
    effects in their expression argument.  Inspired by similar macros in
    systemd.
    
    These are just macros, so they come at no extra cost.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741026

 docs/reference/glib/glib-sections.txt |    3 ++
 glib/gmessages.h                      |   44 ++++++++++++++++++++++++++++++++-
 glib/gtestutils.c                     |   19 ++++++++++++++
 glib/gtestutils.h                     |    2 +
 4 files changed, 67 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 20b7101..cfffbfc 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -973,6 +973,8 @@ g_set_printerr_handler
 <SUBSECTION>
 g_return_if_fail
 g_return_val_if_fail
+g_return_if_fail_se
+g_return_val_if_fail_se
 g_return_if_reached
 g_return_val_if_reached
 g_warn_if_fail
@@ -2976,6 +2978,7 @@ g_test_rand_double
 g_test_rand_double_range
 
 g_assert
+g_assert_se
 g_assert_not_reached
 
 g_assert_cmpstr
diff --git a/glib/gmessages.h b/glib/gmessages.h
index 497c669..d1dbc62 100644
--- a/glib/gmessages.h
+++ b/glib/gmessages.h
@@ -342,11 +342,50 @@ GPrintFunc      g_set_printerr_handler  (GPrintFunc      func);
  * returned from the current function.
  *
  * If G_DISABLE_CHECKS is defined then the check is not performed.  You
- * should therefore not depend on any side effects of @expr.
+ * should therefore not depend on any side effects of @expr.  See
+ * g_return_if_fail_se() for a version that guarantees side effects.
  */
 #define g_return_val_if_fail(expr,val) G_STMT_START{ (void)0; }G_STMT_END
 
 /**
+ * g_return_if_fail_se:
+ * @expr: the expression to check
+ *
+ * Verifies that the expression @expr, usually representing a
+ * precondition, evaluates to %TRUE.
+ *
+ * This is the same as g_return_if_fail() except that @expr is
+ * guaranteed to be evaluated, so it may contain side effects.
+ *
+ * Note: it is still undefined if this function will actually return or
+ * not, or if any side effects of @val will be evaluated.  There is only
+ * a guarantee with respect to side effects of @expr.
+ *
+ * Since: 2.44
+ */
+#define g_return_if_fail_se(expr)         ((void) (expr))
+
+/**
+ * g_return_val_if_fail_se:
+ * @expr: the expression to check
+ * @val: the value to return from the current function
+ *       if the expression is not true
+ *
+ * Verifies that the expression @expr, usually representing a
+ * precondition, evaluates to %TRUE.
+ *
+ * This is the same as g_return_val_if_fail() except that @expr is
+ * guaranteed to be evaluated, so it may contain side effects.
+ *
+ * Note: it is still undefined if this function will actually return or
+ * not, or if any side effects of @val will be evaluated.  There is only
+ * a guarantee with respect to side effects of @expr.
+ *
+ * Since: 2.44
+ */
+#define g_return_val_if_fail_se(expr,val) ((void) (expr))
+
+/**
  * g_return_if_reached:
  *
  * Logs a critical message and returns from the current function.
@@ -382,6 +421,9 @@ GPrintFunc      g_set_printerr_handler  (GPrintFunc      func);
         return (val);                                                  \
        };                              }G_STMT_END
 
+#define g_return_if_fail_se(expr)         g_return_if_fail((expr))
+#define g_return_val_if_fail_se(expr,val) g_return_val_if_fail((expr), (val))
+
 #define g_return_if_reached()          G_STMT_START{                   \
      g_log (G_LOG_DOMAIN,                                              \
            G_LOG_LEVEL_CRITICAL,                                       \
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index e67078d..dede38a 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -316,6 +316,25 @@
  *
  * The macro can be turned off in final releases of code by defining
  * `G_DISABLE_ASSERT` when compiling the application.
+ *
+ * For a version which is guaranteed to evaluate side effects in @expr,
+ * see g_assert_se().
+ */
+
+/**
+ * g_assert_se:
+ * @expr: the expression to check
+ *
+ * Debugging macro to terminate the application if the assertion
+ * fails. If the assertion fails (i.e. the expression is not true),
+ * an error message is logged and the application is terminated.
+ *
+ * The check can be turned off in final releases of code by defining
+ * `G_DISABLE_ASSERT` when compiling the application.
+ *
+ * Unlike g_assert(), this macro is guaranteed to evaluate side effects
+ * of @expr, even if checks are disabled.  It is still undefined if the
+ * program will actually be aborted or not.
  */
 
 /**
diff --git a/glib/gtestutils.h b/glib/gtestutils.h
index 95e6de1..2e27a2a 100644
--- a/glib/gtestutils.h
+++ b/glib/gtestutils.h
@@ -83,12 +83,14 @@ typedef void (*GTestFixtureFunc) (gpointer      fixture,
 #ifdef G_DISABLE_ASSERT
 #define g_assert_not_reached()          do { (void) 0; } while (0)
 #define g_assert(expr)                  do { (void) 0; } while (0)
+#define g_assert_se(expr)               ((void) (expr))
 #else /* !G_DISABLE_ASSERT */
 #define g_assert_not_reached()          do { g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, 
G_STRFUNC, NULL); } while (0)
 #define g_assert(expr)                  do { if G_LIKELY (expr) ; else \
                                                g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, 
G_STRFUNC, \
                                                                          #expr); \
                                            } while (0)
+#define g_assert_se(expr)               g_assert((expr))
 #endif /* !G_DISABLE_ASSERT */
 
 GLIB_AVAILABLE_IN_ALL


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