Timeline for Avoiding repetition when using the "snprintf idiom" to write text
Current License: CC BY-SA 4.0
12 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jul 2, 2019 at 12:14 | comment | added | Will |
@CacahueteFrito I think returning from a macro is fine as long as you're consistent and transparent about it. For example I use the following extensively in my code: #define FOO_GUARD(func_call) do { foo_ret ret = (func_call); if (ret != FOO_OK) return ret; } while (0) , which allows return value checking of any function call with a simple FOO_GUARD(do_something(a, b, c)); ; provided that you design all functions with a consistent return type. E.g., I like having all my functions return foo_ret defined as typedef enum { FOO_OK = 0, FOO_E_MALLOC = 1, FOO_E_.....etc } foo_ret .
|
|
Jul 2, 2019 at 11:46 | comment | added | alx - recommends codidact |
1.b) I didn't mean to actually return , but to simulate a return; actually evaluate the macro to a value of type int , which can be done only by using the GCC extension. However, a function would make more sense with all that error checking.
|
|
Jul 2, 2019 at 11:45 | comment | added | alx - recommends codidact |
1) using any of the following inside a macro is not a good idea: return , goto (if it goes out of the macro; or to something other than __label__ ), break or continue (that's actually Ok being inside a do while ), exit() . Users of the macro might get surprised, and that could cause bugs.
|
|
Jul 2, 2019 at 11:38 | comment | added | alx - recommends codidact | 2) Fine. 3) Touche. I didn't intend to offer a full solution, just to note the reordering; but yes, an answer should not be unsafe even if it isn't trying to be complete. Fixed that. | |
Jul 2, 2019 at 6:40 | comment | added | Will |
@CacahueteFrito 2) One could easily modify the macro to add a layer of indirection, such that the 1st parameter becomes &buff instead of buff , but personally I don't really see the need to cross-dress like a function. 3) Indeed, snprinf() may fail, so why doesn't your own answer account for that?
|
|
Jul 2, 2019 at 6:17 | comment | added | Will |
@CacahueteFrito 1) You can make FOO_MALLOC_ERR expand to whatever you want (e.g., directly returning an int or enum: return FOO_E_MALLOC , provided that your codebase has a consistent policy regarding return values). However, if you don't like that, you could replace the last 4 lines of the macro with if (_str) { sprintf(_str, __VA_ARGS__); } instead, at which point it is exactly the same as the accepted answer above as far as err handling is concerned: check if the resulting buffer is null on the line below the macro invocation vs on the line below the function invocation.
|
|
Jul 2, 2019 at 4:52 | comment | added | alx - recommends codidact |
Also, the fact that it modifies a variable without taking its address is something weird (the capital letters mitigate that, but it's still weird). Pedantic: snprintf() may fail: EILSEQ or EOVERFLOW (altough unlikely): pubs.opengroup.org/onlinepubs/9699919799/functions/…
|
|
Jul 2, 2019 at 4:49 | comment | added | alx - recommends codidact |
The main problem I see is it doesn't return an error code. It would be more complicated to handle errors. Maybe the GCC extension ({}) would be more appropriate: gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
|
|
Jun 30, 2019 at 23:39 | history | edited | Will | CC BY-SA 4.0 |
added 1 character in body
|
Jun 30, 2019 at 23:32 | history | edited | Will | CC BY-SA 4.0 |
added 29 characters in body
|
Jun 30, 2019 at 23:25 | history | edited | Will | CC BY-SA 4.0 |
added 91 characters in body
|
Jun 30, 2019 at 23:17 | history | answered | Will | CC BY-SA 4.0 |