From: Rich Felker Date: Tue, 28 Aug 2018 17:54:50 +0000 (-0400) Subject: fix dubious char signedness check in limits.h X-Git-Tag: v1.1.20~20 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=cdbbcfb8f5d748f17694a5cc404af4b9381ff95f;p=oweals%2Fmusl.git fix dubious char signedness check in limits.h commit 201995f382cc698ae19289623cc06a70048ffe7b introduced a hack utilizing the signedness of character constants at the preprocessor level to avoid depending on the gcc-specific __CHAR_UNSIGNED__ predef. while this trick works on gcc and presumably other compilers being used, it's not clear that the behavior it depends on is actually conforming. C11 6.4.4.4 ¶10 defines character constants as having type int, and 6.10.1 ¶4 defines preprocessor #if arithmetic to take place in intmax_t or uintmax_t, depending on the signedness of the integer operand types, and it is specified that "this includes interpreting character constants". if character literals had type char and just promoted to int, it would be clear that when char is unsigned they should behave as uintmax_t at the preprocessor level. however, as written the text of the standard seems to require that character constants always behave as intmax_t, corresponding to int, at the preprocessor level. since there is a good deal of ambiguity about the correct behavior and a risk that compilers will disagree or that an interpretation may mandate a change in the behavior, do not rely on it for defining CHAR_MIN and CHAR_MAX correctly. instead, use the signedness of the value (as opposed to the type) of '\xff', which will be positive if and only if plain char is unsigned. this behavior is clearly specified, and the specific case '\xff' is even used in an example, under 6.4.4.4 of the standard. --- diff --git a/include/limits.h b/include/limits.h index ab163a22..02c2139d 100644 --- a/include/limits.h +++ b/include/limits.h @@ -9,7 +9,7 @@ /* Support signed or unsigned plain-char */ -#if '\0'-1 > 0 +#if '\xff' > 0 #define CHAR_MIN 0 #define CHAR_MAX 255 #else