Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: on ``warning: array subscript has type =?utf-8?B?4oCYY2hhcg==?= =?utf-8?B?4oCZJyc=?= Date: Mon, 06 Dec 2021 13:12:40 -0800 Organization: None to speak of Lines: 40 Message-ID: <87v901bfp3.fsf@nosuchdomain.example.com> References: <86mtldsbzf.fsf@levado.to> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="8a44e9d9a9b2a2115bfb2aee4d38e675"; logging-data="4961"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18+ALRoyvLXeY+DKp940phy" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:j8TpB+CqyTupSegfKQ8m9Ti+ydM= sha1:6BLnzxySspq+YQ1EjjLyrKSZfT4= Xref: csiph.com comp.lang.c:163728 Meredith Montgomery writes: > I can't explain this. > > %make warning > gcc -Wall -x c -g -std=c99 -pedantic-errors warning.c -o warning > In file included from warning.c:2: > warning.c: In function ‘getop’: > warning.c:38:27: warning: array subscript has type ‘char’ [-Wchar-subscripts] > 38 | while (isdigit(s[++i] = c = getch())) > | ~~~~~~~^~~~~~~~~~~~~ > > I understand the warning is trying to tell me that a char is not a good > idea as an array subscript as a char could be negative. However, the > array subscript is /i/, not /c/. So I'm puzzled. Thank you! [...] The isdigit() function is probably implemented as a macro that uses array indexing. (All library functions can also be implemented as macros.) The part of the compiler that generates the warning message doesn't know that the array indexing operator is the result of a macro expansion, so it warns you as if you had written the indexing operator directly. If you replace `isdigit` by `(isdigit)` or precede the call by #undef isdigit it will bypass the macro and call the actual function, and you probably won't see the warning. I suggest this as a diagnostic method, not as a solution. Having said that, the warning is quite useful even if it's less than clear. The argument to isdigit() is of type int, and is required to be either within the range of unsigned char *or* equal to EOF (which is typically -1). Which means, annoyingly, that a char value passed to isdigit() and friends should be cast to unsigned char. Passing a negative char value (other than EOF) to isdigit() has undefined behavior. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */