diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-03-14 14:44:54 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-03-14 18:18:24 +0100 |
commit | 56da8d5af37bda6950f058066fa05c5fdcc20f6e (patch) | |
tree | 53474755b81812e382ad7f3450f39969aa2088c6 /src/basic/macro.h | |
parent | test: add test for DECIMAL_STR_WIDTH() (diff) | |
download | systemd-56da8d5af37bda6950f058066fa05c5fdcc20f6e.tar.xz systemd-56da8d5af37bda6950f058066fa05c5fdcc20f6e.zip |
macro: handle DECIMAL_STR_MAX() special cases more accurately
So far DECIMAL_STR_MAX() overestimated the types in two ways: it would
also adds space for a "-" for unsigned types.
And it would always return the same size for 64bit values regardless of
signedness, even though the longest maximum numbers for signed and
unsigned differ in length by one digit. i.e. 2^64-1 (i.e. UINT64_MAX) is
one decimal digit longer than -2^63 (INT64_MIN) - for the other integer
widths the number of digits in the "longest" decimal value is always the
same, regardless of signedness. by example: strlen("65535") ==
strlen("32768") (i.e. the relevant 16 bit limits) holds — and similar
for 8bit and 32bit integer width limits — but
strlen("18446744073709551615") > strlen("9223372036854775808") (i.e. the
relevant 64 bit limits).
Let's fix both misestimations.
Diffstat (limited to 'src/basic/macro.h')
-rw-r--r-- | src/basic/macro.h | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/src/basic/macro.h b/src/basic/macro.h index 214654386c..fb1ae65d28 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -309,15 +309,14 @@ static inline int __coverity_check_and_return__(int condition) { #define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member) -/* Returns the number of chars needed to format variables of the - * specified type as a decimal string. Adds in extra space for a - * negative '-' prefix (hence works correctly on signed - * types). Includes space for the trailing NUL. */ +/* Returns the number of chars needed to format variables of the specified type as a decimal string. Adds in + * extra space for a negative '-' prefix for signed types. Includes space for the trailing NUL. */ #define DECIMAL_STR_MAX(type) \ - (2U+(sizeof(type) <= 1 ? 3U : \ + ((size_t) IS_SIGNED_INTEGER_TYPE(type) + 1U + \ + (sizeof(type) <= 1 ? 3U : \ sizeof(type) <= 2 ? 5U : \ sizeof(type) <= 4 ? 10U : \ - sizeof(type) <= 8 ? 20U : sizeof(int[-2*(sizeof(type) > 8)]))) + sizeof(type) <= 8 ? (IS_SIGNED_INTEGER_TYPE(type) ? 19U : 20U) : sizeof(int[-2*(sizeof(type) > 8)]))) /* Returns the number of chars needed to format the specified integer value. It's hence more specific than * DECIMAL_STR_MAX() which answers the same question for all possible values of the specified type. Does |