diff options
author | Thomas Haller <thaller@redhat.com> | 2015-11-11 13:33:46 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-11-18 13:25:21 +0100 |
commit | 37824def11c2c7947103ae668ec487bc90c10c35 (patch) | |
tree | d99eddb56c8387a404cfe72de0a6f6586ed1c8d2 | |
parent | 0c65b289601d46edb0a950e291ddd376e368ccfd (diff) |
all: add C99's "bool" define
https://mail.gnome.org/archives/networkmanager-list/2015-November/msg00036.html
-rw-r--r-- | include/nm-default.h | 47 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 8 |
2 files changed, 55 insertions, 0 deletions
diff --git a/include/nm-default.h b/include/nm-default.h index d5c9d1064d..70069a92e8 100644 --- a/include/nm-default.h +++ b/include/nm-default.h @@ -70,4 +70,51 @@ /*****************************************************************************/ +/** + * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too + * convinient to miss and is effectively available in gcc and clang. So, just use it. + * + * Usually, one would include "stdbool.h" to get the "bool" define which aliases + * _Bool. We provide this define here, because we want to make use of it anywhere. + * (also, stdbool.h is again C99). + * + * Using _Bool has advantages over gboolean: + * + * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean + * is a typedef for gint). Especially when having boolean fields in a struct, we can + * thereby easily save some space. + * + * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing + * will not work: + * gboolean v1 = 1; + * gboolean v2 = 2; + * g_assert_cmpint (v1, ==, v2); // will fail + * For that, we often to use !! to coerce gboolean values to 0 or 1: + * g_assert_cmpint (!!v2, ==, TRUE); + * With _Bool type, this will be handled properly by the compiler. + * + * - For structs, we might want to safe even more space and use bitfields: + * struct s1 { + * gboolean v1:1; + * }; + * But the problem here is that gboolean is signed, so that + * v1 will be either 0 or -1 (not 1, TRUE). Thus, the following + * fails: + * struct s1 s = { .v1 = TRUE, }; + * g_assert_cmpint (s1.v1, ==, TRUE); + * It will however work just fine with bool/_Bool while retaining the + * notion of having a boolean value. + * + * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor + * as special types, contrary to glib's "TRUE"/"FALSE". + */ + +#ifndef bool +#define bool _Bool +#define true 1 +#define false 0 +#endif + +/*****************************************************************************/ + #endif /* __NM_DEFAULT_H__ */ diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 2873f755ac..5d95f26aed 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -65,6 +65,14 @@ #include "nm-test-utils.h" #include "test-general-enums.h" +/* When passing a "bool" typed argument to a variadic function that + * expects a gboolean, the compiler will promote the integer type + * to have at least size (int). That way: + * g_object_set (obj, PROP_BOOL, bool_val, NULL); + * will just work correctly. */ +G_STATIC_ASSERT (sizeof (gboolean) == sizeof (int)); +G_STATIC_ASSERT (sizeof (bool) <= sizeof (int)); + static void vpn_check_func (const char *key, const char *value, gpointer user_data) { |