I have the following code to read an argument from the command line. If the string is 1 character long and a digit I want to use that as the exit value. The compiler gives me a warning on the second line (array subscript has type ‘char’ ) This error comes from the second part after the “&&” .
if (args[1] != NULL) {
if ((strlen(args[1]) == 1) && isdigit(*args[1]))
exit(((int) args[1][0]));
else
exit(0);
}
}
Also, when I use a different compiler I get two errors on the next line (exit).
builtin.c: In function 'builtin_command':
builtin.c:55: warning: implicit declaration of function 'exit'
builtin.c:55: warning: incompatible implicit declaration of built-in function 'exit'
The trouble is that the
isdigit()macro takes an argument which is an integer that is either the value EOF or the value of anunsigned char.ISO/IEC 9899:1999 (C Standard – old), §7.4 Character handling
<ctype.h>, ¶1:On your platform,
charis signed, so if you have a character in the range 0x80..0xFF, it will be treated as a negative integer. The usual implementation of theisdigit()macros is to use the argument to index into an array of flag bits. Therefore, if you pass acharfrom the range 0x80..0xFF, you will be indexing before the start of the array, leading to undefined behaviour.You can safely use
isdigit()in either of two ways:or:
In the latter case, you know that the value won’t be EOF. Note that this is not OK:
The warning about ‘implicit definition of function exit’ means you did not include
<stdlib.h>but you should have done so.You might also notice that if the user gives you a 2 as the first character of the first argument, the exit status will be 50, not 2, because
'2'is (normally, in ASCII and UTF-8 and 8859-1, etc) character code 50 ('0'is 48, etc). You’d get2(no quotes) by using*args[1] - '0'as the argument toexit(). You don’t need a cast on that expression, though it won’t do much harm.