473,890 Members | 2,038 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

array subscript type cannot be `char`?

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>
Mar 22 '06
51 23782
Pedro Graca <he****@dodgeit .com> writes:
Keith Thompson wrote:

[...]
If CHAR_BIT==8, plain char may be either signed or unsigned.

If CHAR_BIT==8 and '0'==0xF0 (as it is in ECBDIC), then plain char
must be unsigned.


I realize that no matter what character set the implementation defines
or what CHAR_BIT is for the implementation, *all* characters in the
basic set defined by the Standard (digits, lowercase and uppercase
letters, <tab>, <newline>, and a few signs, ...) must be positive.
There is no guarantee for characters outside this set:

char *p = "Pedro Graça";
int i=0;
while (*p) {
charval[*p] = i++; /* possible BANG! for 'ç' */
++p;
}


And even for characters within the basic set, it's not a guarantee
that I'd want to depend on. There's no problem in the above code if I
use my own name rather than yours, but I'd still want to make sure it
works for any possible character value, probably by casting to
unsigned char. It's too easy to change the code to use a different
string literal or to get its data from somewhere else, and it's easier
to avoid the situation altogether than to document the assumption.

Even seemingly innocuous characters like '$', I think, are outside the
basic characater set; I'd be astonished to see an implementation where
'$'<0, but I'll probably run into one at the most inconvenient
possible moment.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <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.
Mar 27 '06 #41
Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))
Mar 27 '06 #42
Jordan Abel schrieb:
Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))


Hmmm. Nice until x is something with sideeffects like, say,
"c = getchar()".

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 27 '06 #43
On Sun, 26 Mar 2006 20:59:16 +0000 (UTC), in comp.lang.c , "Herbert
Rosenau" <os****@pc-rosenau.de> wrote:
On Fri, 24 Mar 2006 19:56:13 UTC, Keith Thompson <ks***@mib.or g>
wrote:
Mark McIntyre <ma**********@s pamcop.net> writes:
> However, the general case is precisely as Herbert wrote.


Yes, but nobody was asking about the general case.


And frequently, we correct people's spelling, and fix bugs they didn't
spot, even though they didn't ask about that either.
We're discussing standard C here, not EBCDIC C.


I agree. But IMHO, and ICBW, you (and initially I) misunderstood the
thread to be about the general case when it was actually about a
specific one and thus technically offtopic. No harm done, either way.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 27 '06 #44
On 2006-03-27, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:
Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))


Hmmm. Nice until x is something with sideeffects like, say,
"c = getchar()".


That's why it's uppercase. To warn you.
Mar 27 '06 #45
Jordan Abel schrieb:
On 2006-03-27, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:
Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))


Hmmm. Nice until x is something with sideeffects like, say,
"c = getchar()".


That's why it's uppercase. To warn you.


For functionality as basic as this, I do not trust anyone
to use it consistently correctly -- including me. I remember
a then-colleague abusing a macro with the words "Oh, it's
from XY -- he surely did something clever"... ;-(

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Mar 28 '06 #46
On 2006-03-28, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:
On 2006-03-27, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:

Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))

Hmmm. Nice until x is something with sideeffects like, say,
"c = getchar()".


That's why it's uppercase. To warn you.


For functionality as basic as this, I do not trust anyone
to use it consistently correctly -- including me. I remember
a then-colleague abusing a macro with the words "Oh, it's
from XY -- he surely did something clever"... ;-(


as it turns out, i _did_ do something clever. x is evaluated only once.

--
look closer...
Mar 28 '06 #47
Jordan Abel wrote:

Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))


I don't understand what that macro is for, or how you would use it.
If you would cast a byte sized type to unsigned char,
why wouldn't you cast a larger type to unsigned char?

--
pete
Mar 28 '06 #48
Jordan Abel wrote:
On 2006-03-28, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:
On 2006-03-27, Michael Mair <Mi**********@i nvalid.invalid> wrote:
Jordan Abel schrieb:

> Note: No context quoted because I'm replying to the actual
> issue the thread brings up rather than to any particular post
>
> What all this is missing is that it's silly to warn on an
> array subscript of type char when you don't warn on one of type
> signed int.
>
> Idea -- magic safe macro for isalpha:
>
> #define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))

Hmmm. Nice until x is something with sideeffects like, say,
"c = getchar()".

That's why it's uppercase. To warn you.


For functionality as basic as this, I do not trust anyone
to use it consistently correctly -- including me. I remember
a then-colleague abusing a macro with the words "Oh, it's
from XY -- he surely did something clever"... ;-(


as it turns out, i _did_ do something clever. x is evaluated
only once.


There you go - somebody finally noticed.

--
"If you want to post a followup via groups.google.c om, 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/googlegroupsrep ly/>

Mar 28 '06 #49
On 2006-03-28, pete <pf******@minds pring.com> wrote:
Jordan Abel wrote:

Note: No context quoted because I'm replying to the actual issue the
thread brings up rather than to any particular post

What all this is missing is that it's silly to warn on an array
subscript of type char when you don't warn on one of type signed int.

Idea -- magic safe macro for isalpha:

#define ISALPHA(x) isalpha(sizeof( x)==1?(unsigned char)(x):(x))


I don't understand what that macro is for, or how you would use it.
If you would cast a byte sized type to unsigned char,
why wouldn't you cast a larger type to unsigned char?


Because the larger type is likely to be an int which is safe to use
since it will be valued either EOF or between 0 and UCHAR_MAX [e.g. the
result from getc] the issue is that a char value could be a negative
number other than EOF.
Mar 28 '06 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.