Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > array subscript type cannot be `char`?

Reply
Thread Tools

array subscript type cannot be `char`?

 
 
Pedro Graca
Guest
Posts: n/a
 
      03-22-2006
I run into a strange warning (for me) today (I was trying to improve
the score of the UVA #10018 Programming Challenge).

$ gcc -W -Wall -std=c89 -pedantic -O2 10018-clc.c -o 10018-clc
10018-clc.c: In function `main':
10018-clc.c:22: warning: array subscript has type `char'

I don't like warnings ... or casts.


#include <stdio.h>

#define SIGNEDNESS
/* #define SIGNEDNESS signed */ /* either of these */
/* #define SIGNEDNESS unsigned */ /* defines "works" */

static int charval['9' + 1];
static unsigned long x;

int main(void) {
SIGNEDNESS char test[] = "9012";
SIGNEDNESS char *p = test;

charval['1'] = 1;
charval['2'] = 2;
/* similarly for 3 to 8 */
charval['9'] = 9;

x = 0; /* redundant */
while (*p) {
x *= 10;
x += charval[*p]; /* line 22 */

/* casts to get rid of warning: all of them "work"! */
/* x += charval[ (int) *p]; */
/* x += charval[ (size_t) *p]; */
/* x += charval[ (unsigned) *p]; */
/* x += charval[ (long) *p]; */
/* x += charval[ (wchar_t) *p]; */
/* x += charval[ (signed char) *p]; */
/* x += charval[ (unsigned char) *p]; */

++p;
}

printf("%lu\n", x);
return 0;
}


Is this only a question of portability? (I realize the warning appears
only because of the -Wall option to gcc)

What is the type of an array subscript?
I'd guess size_t, and other types would be promoted automatically.

Should I make an effort to declare all char stuff as either signed or
unsigned? ... before it runs on a DS 9000

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
 
Reply With Quote
 
 
 
 
Robert Gamble
Guest
Posts: n/a
 
      03-22-2006

Pedro Graca wrote:
> I run into a strange warning (for me) today (I was trying to improve
> the score of the UVA #10018 Programming Challenge).
>
> $ gcc -W -Wall -std=c89 -pedantic -O2 10018-clc.c -o 10018-clc
> 10018-clc.c: In function `main':
> 10018-clc.c:22: warning: array subscript has type `char'


[snip example program using char subscript]

There is technically nothing "wrong" about using char as an array
subscript, any integer type is legal as an array subscript.

According to the rationale for this warning in the gcc documentation,
many programmers forget the fact that char can be signed which could
obviously lead to unexpected problems if the char value was negative.
This warning is enabled with the -Wall option and can be disabled by
using -Wno-char-subscripts.

Robert Gamble

 
Reply With Quote
 
 
 
 
Old Wolf
Guest
Posts: n/a
 
      03-22-2006
Pedro Graca wrote:

> int main(void) {
> SIGNEDNESS char test[] = "9012";
> SIGNEDNESS char *p = test;
>
> charval['1'] = 1;
> charval['2'] = 2;
> /* similarly for 3 to 8 */
> charval['9'] = 9;
>
> x = 0; /* redundant */
> while (*p) {
> x *= 10;
> x += charval[*p]; /* line 22 */


The warning is because chars can be negative, and a negative
subscript to an array will cause undefined behaviour. If you happen
to include some negative chars in test[], then you have UB.

This is not a required diagnostic; I guess the GCC developers feel
that this error is more likely to occur with a char than with other
signed integral types

> Should I make an effort to declare all char stuff as either signed or
> unsigned? ... before it runs on a DS 9000


Just make sure your code does not rely on chars being either
signed or unsigned.
If you need to rely on unsignedness (eg. an array of all possible
char values) then you should explicitly use unsigned chars.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-22-2006
Pedro Graca <(E-Mail Removed)> writes:
> I run into a strange warning (for me) today (I was trying to improve
> the score of the UVA #10018 Programming Challenge).
>
> $ gcc -W -Wall -std=c89 -pedantic -O2 10018-clc.c -o 10018-clc
> 10018-clc.c: In function `main':
> 10018-clc.c:22: warning: array subscript has type `char'
>
> I don't like warnings ... or casts.
>

[code snipped]
>
> Is this only a question of portability? (I realize the warning appears
> only because of the -Wall option to gcc)


I think the point is that char can be either signed or unsigned,
depending on the implementation. Code that works properly where plain
char is unsigned might fail on another platform where plain char is
signed:

int arr[256];
char index = 200;
... arr[index] ...

Presumably if you use "signed char" explicitly, the compiler assumes
you know what you're doing.

Using plain int as an array index doesn't present the same problem,
because plain int is always signed; any problems will show up on any
platform.

> What is the type of an array subscript?
> I'd guess size_t, and other types would be promoted automatically.


The index merely has to have some integer type.

> Should I make an effort to declare all char stuff as either signed or
> unsigned? ... before it runs on a DS 9000


If the actual values are always going to be in the range 0..127, it
shouldn't matter. If they can exceed 127 (the minimum possible value
of CHAR_MAX), you might consider either declaring your variables as
unsigned char, or casting to unsigned char when indexing:

int arr[256];
char index = 200;
... arr[(unsigned char)index] ...

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Ben C
Guest
Posts: n/a
 
      03-22-2006
On 2006-03-22, Old Wolf <(E-Mail Removed)> wrote:
> The warning is because chars can be negative, and a negative subscript
> to an array will cause undefined behaviour.


Are you sure? There's nothing undefined about this:

#include <stdio.h>

int main(void)
{
int x[10];
int *y = x + 5;
y[-1] = 100;

printf("%d\n", y[-1]);

return 0;
}
 
Reply With Quote
 
Pedro Graca
Guest
Posts: n/a
 
      03-22-2006
Old Wolf wrote:
> Pedro Graca wrote:
>> Should I make an effort to declare all char stuff as either signed or
>> unsigned? ... before it runs on a DS 9000

>
> Just make sure your code does not rely on chars being either
> signed or unsigned.
> If you need to rely on unsignedness (eg. an array of all possible
> char values) then you should explicitly use unsigned chars.


Thank you for your answers.

Is it guaranteed that all characters available on some implementation
for which there is a standards compliant compiler are positive?

AFAICT, in EBCDIC the character '0' has value 0xF0.
Assuming CHAR_BIT is 8 does it follow that plain char is unsigned
for conforming compilers?

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      03-22-2006
Pedro Graca wrote:
>

.... snip ...
>
> Is it guaranteed that all characters available on some implementation
> for which there is a standards compliant compiler are positive?
>
> AFAICT, in EBCDIC the character '0' has value 0xF0.
> Assuming CHAR_BIT is 8 does it follow that plain char is unsigned
> for conforming compilers?


No. However all chars in the required char set, which includes
'0'..'9', 'a'..'z', 'A'..'Z', '+-*!@#%^&(){}[]:;'"?\/<>.,' must be
positive.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>


 
Reply With Quote
 
Kenneth Brody
Guest
Posts: n/a
 
      03-22-2006
Pedro Graca wrote:
>
> I run into a strange warning (for me) today (I was trying to improve
> the score of the UVA #10018 Programming Challenge).
>
> $ gcc -W -Wall -std=c89 -pedantic -O2 10018-clc.c -o 10018-clc
> 10018-clc.c: In function `main':
> 10018-clc.c:22: warning: array subscript has type `char'
>
> I don't like warnings ... or casts.
>
> #include <stdio.h>
>
> #define SIGNEDNESS
> /* #define SIGNEDNESS signed */ /* either of these */
> /* #define SIGNEDNESS unsigned */ /* defines "works" */

[...]
> SIGNEDNESS char *p = test;

[...]
> x += charval[*p]; /* line 22 */

[...]
> /* casts to get rid of warning: all of them "work"! */

[...]
> /* x += charval[ (signed char) *p]; */
> /* x += charval[ (unsigned char) *p]; */

[...]

Given that explicitly using "unsigned char" or "signed char" will both
get rid of the warning, my guess is that it's your compiler's way of
pointing out "hey, char can be signed in some environments, and unsigned
in others, so using a plain 'char' as a subscript may not necessarily be
what you want to do here".

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <(E-Mail Removed)>

 
Reply With Quote
 
Robert Gamble
Guest
Posts: n/a
 
      03-22-2006
Ben C wrote:
> On 2006-03-22, Old Wolf <(E-Mail Removed)> wrote:
> > The warning is because chars can be negative, and a negative subscript
> > to an array will cause undefined behaviour.

>
> Are you sure? There's nothing undefined about this:
>
> #include <stdio.h>
>
> int main(void)
> {
> int x[10];
> int *y = x + 5;
> y[-1] = 100;
>
> printf("%d\n", y[-1]);
>
> return 0;
> }


y is not an array, it is a pointer.

Robert Gamble

 
Reply With Quote
 
Richard G. Riley
Guest
Posts: n/a
 
      03-22-2006
On 2006-03-22, Robert Gamble <(E-Mail Removed)> wrote:
> Ben C wrote:
>> On 2006-03-22, Old Wolf <(E-Mail Removed)> wrote:
>> > The warning is because chars can be negative, and a negative subscript
>> > to an array will cause undefined behaviour.

>>
>> Are you sure? There's nothing undefined about this:
>>
>> #include <stdio.h>
>>
>> int main(void)
>> {
>> int x[10];
>> int *y = x + 5;
>> y[-1] = 100;
>>
>> printf("%d\n", y[-1]);
>>
>> return 0;
>> }

>
> y is not an array, it is a pointer.
>
> Robert Gamble
>


Looks kind of ok to me : am I being too lax with pointers in thinking that?

It seems to my (becoming "more standard") eye, that y points to x[5],
and so y[-1] is perfectly valid since arr[-1] is the same as
*(arr-1). And since "arr" (or y) points into a valid data area then it
is defined. Is this wrong?






--
Debuggers : you know it makes sense.
http://heather.cs.ucdavis.edu/~matlo...g.html#tth_sEc
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
invalid types `unsigned char[int]' for array subscript uche C++ 3 02-26-2007 09:30 AM
invalid types `unsigned char[int]' for array subscript uche C++ 0 02-26-2007 07:25 AM
how to overload subscript of 2D-array DaVinci C++ 5 05-10-2006 10:31 PM
out of range array subscript Richard Delorme C Programming 5 05-15-2004 03:42 PM
Order of uknown array subscript Tom Page C++ 4 02-17-2004 02:55 PM



Advertisments