Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learn C The Hard Way exercise 14 Error (warning: array subscript has type ?char? [-Wchar-subscripts]

Tags:

c

I'm following along that tutorial, I'm running WindowsXP 32-bit with cygwin compiler, The tutorial asks me to run this code:

#include <stdio.h>
#include <ctype.h>

// forward declarations
int can_print_it(char ch);
void print_letters(char arg[]);

void print_arguments(int argc, char *argv[])
{
    int i = 0;

    for(i = 0; i < argc; i++) {
        print_letters(argv[i]);
    }
}

void print_letters(char arg[])
{
    int i = 0;

    for(i = 0; arg[i] != '\0'; i++) {
        char ch = arg[i];

        if(can_print_it(ch)) {
            printf("'%c' == %d ", ch, ch);
        }
    }

    printf("\n");
}

int can_print_it(char ch)
{
    return isalpha(ch) || isblank(ch);
}


int main(int argc, char *argv[])
{
    print_arguments(argc, argv);
    return 0;
}

But I keep running into this warning:

$ make ex14
cc -Wall -g    ex14.c   -o ex14
ex14.c: In function ?can_print_it?:
ex14.c:34:5: warning: array subscript has type ?char? [-Wchar-subscripts]
    return isalpha(ch) || isblank(ch);
    ^
ex14.c:34:5: warning: array subscript has type ?char? [-Wchar-subscripts]

I have tried searching around, while I have found a lot of threads talking about a similar error, none of their answers/solutions worked on my code, and I couldn't find a question related to Learn C The Hard Way exercise 14.

So what should I do to get rid of that warning?

like image 351
no_name Avatar asked Mar 18 '23 06:03

no_name


2 Answers

The reason for the warning is that char values are usually positive, but sometimes they may be negative; this may come unexpected to the programmer (especially because on some implementations char is always positive), and using a negative index for an array is obviously a bad thing.

isalpha does exactly that behind your back. You fix the warning by casting the char to int or by storing it in an int in the first place - this doesn't fix the problem though, because a negative char will be cast to a negative int which has exactly the same problem. You can fix the warning and the problem by casting the char to an unsigned char.

like image 167
gnasher729 Avatar answered Apr 09 '23 00:04

gnasher729


So if we look at the gcc document for warnings which covers -Wchar-subscripts it says:

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.

It is implementation defined whether char is signed or unsigned, if you use an unsigned char then the warning will go away.

We can see from the draft C99 standard that the arguments to functions in <ctype.h> are expected to be representable as unsigned char or EOF, from section 7.4 Character handling <ctype.h>:

In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined

So most likely isalpha and isblank are implemented as a macro which uses a lookup table and so this code would indeed be using a char to index an array.

like image 20
Shafik Yaghmour Avatar answered Apr 08 '23 23:04

Shafik Yaghmour