dtc icon indicating copy to clipboard operation
dtc copied to clipboard

Char subscript error in Cygwin

Open longr96 opened this issue 2 years ago • 4 comments

I'm getting the following error when building in Cygwin

checks.c:1183:52: error: array subscript has type 'char' [-Werror=char-subscripts] 1183 | if (unitname[0] == '0' && isxdigit(unitname[1]))

I guess all that needs to be done is to do a type cast on the '1'?

longr96 avatar Aug 23 '22 16:08 longr96

Hmm... if an integer literal can't be used as an array subscript that really seems like a bug with the compiler rather than the code in question.

dgibson avatar Sep 01 '22 02:09 dgibson

I think you are misreading the warning. isxdigit() takes an integer argument and unitname[0] is a char. This is very deliberately a warning by GCC and llvm. This is from the GCC manual:

-Wchar-subscripts Warn if an array subscript has type char. This is a common cause of error, as programmers often forget that this type is signed on some machines. This warning is enabled by -Wall.

The warning should be fixed.

joelsherrill avatar Jan 20 '23 15:01 joelsherrill

I think you are misreading the warning. isxdigit() takes an integer argument and unitname[0] is a char. This is very deliberately a warning by GCC and llvm. This is from the GCC manual:

So, yes, I misread the error as about being the apparent subscripts here rather than the isxdigit() call, but the description of the error still doesn't make the problem apparent.

-Wchar-subscripts Warn if an array subscript has type char. This is a common cause of error, as programmers often forget that this type is signed on some machines. This warning is enabled by -Wall.

Yes, we're expecting unitname[1] to be promoted to int as a parameter to the function isxdigit(), but that doesn't really have anything to do with array subscripts. My best guess here is that the Cygwin isxdigit() is implemented as a macro. If that macro is then indexing a lookup table using the parameter, that would explain this error. If that's the case, I really think that's a bug in the isxdigit() implementation, rather than the code in dtc - although it takes an int for (borderline archaic) technical reasons, isxdigit() is explicitly about testing characters, it seems pretty bogus for it not to be ok to pass a char value to it.

Fwiw, I always compile with -Wall on Linux and I've never seen this error, nor do I see it if I explicitly add -Wchar-subscripts.

The warning should be fixed.

I'm guessing you mean by making it isxdigit((int)unitname[1])?

I'm not thrilled at the prospect of obfuscating the code with an additional cast to work around what's arguably a bug in the library implementation.

dgibson avatar Jan 23 '23 05:01 dgibson

The basic problem is that it is implementation-defined if char is signed or unsigned. See also https://stackoverflow.com/questions/17975913/does-ctype-h-still-require-unsigned-char.

I think all the is*(x) calls from ctype.h should be changed to is*((unsigned char)x).

sebhub avatar Jul 25 '23 05:07 sebhub