From 4c7bfbf87f05e9df16a34198098806e1ac029be9 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Thu, 3 Sep 2020 14:57:05 +0200 Subject: Avoid potential undesirable effects caused by macros The macros provided by this library would expand to an unguarded conditional that could have potential unwanted consequences. Consider the following example: dynstr_append_or_ret_null(&d, "example"); else { /* This is unexpectedly working. */ } The example above would expand to: if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return false; else { /* This is unexpectedly working. */ } Which is valid C yet allows possibly unexpected behaviour. The solution is then to enclose these conditions into a `do while (0)` statement. --- include/dynstr.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/dynstr.h b/include/dynstr.h index a07cf3b..4fc0afa 100644 --- a/include/dynstr.h +++ b/include/dynstr.h @@ -30,12 +30,14 @@ /** * Convenience macro that calls dynstr_append and returns NULL if failed. */ -#define dynstr_append_or_ret_null(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return NULL +#define dynstr_append_or_ret_null(...) \ + do {if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return NULL;} while (0) /** * Convenience macro that calls dynstr_append and returns false if failed. */ -#define dynstr_append_or_ret_false(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return false +#define dynstr_append_or_ret_false(...) \ + do {if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return false;} while (0) /** * Convenience macro that calls dynstr_append and returns its error code if failed. @@ -45,12 +47,14 @@ /** * Convenience macro that calls dynstr_append and returns zero if failed. */ -#define dynstr_append_or_ret_zero(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 0 +#define dynstr_append_or_ret_zero(...) \ + do {if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 0;} while (0) /** * Convenience macro that calls dynstr_append and returns one if failed. */ -#define dynstr_append_or_ret_nonzero(...) if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 1 +#define dynstr_append_or_ret_nonzero(...) \ + do {if (dynstr_append(__VA_ARGS__) != DYNSTR_OK) return 1;} while (0) /** * Dynamic string type used for this library. -- cgit v1.2.3