Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ANSI C: Why character functions accept int argument instead of char argument?

Tags:

c

char

Why character functions accept int argument instead of char argument?

<ctype.h>

int isalnum(int c); 
int isalpha(int c); 
int iscntrl(int c); 
int isdigit(int c); 
int isgraph(int c); 
int islower(int c); 
int isprint(int c); 
int ispunct(int c); 
int isspace(int c); 
int isupper(int c); 
int isxdigit(int c); 
int tolower(int c); 
int toupper(int c); 
like image 582
Amir Saniyan Avatar asked Feb 16 '12 07:02

Amir Saniyan


People also ask

Why is the argument type int in all the character handling functions?

h> declares several functions useful for classifying and mapping characters. 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.

Why does Strchr take an int?

char *strchr(const char *s, int c); because int is what the above legacy implementation expects to physically receive as c . Declaring it with a char parameter would be incorrect. For this reason, you will never see "traditional" standard library functions expecting parameters of type char , short or float .

Why does memset take an int?

memset predates (by quite a bit) the addition of function prototypes to C. Without a prototype, you can't pass a char to a function -- when/if you try, it'll be promoted to int when you pass it, and what the function receives is an int .

Are char and int interchangeable?

Char is short for character, and should be used for strings. Int is used for whole numbers. Never use char for number.


2 Answers

Characters and integers are rather tightly knit in C.

When you receive a character from an input stream, it must be able to represent every single character plus the end-of-file symbol.

That means a char type won't be big enough so they use a wider type.

The C99 rationale document states:

Since these functions are often used primarily as macros, their domain is restricted to the small positive integers representable in an unsigned char, plus the value of EOF. EOF is traditionally -1, but may be any negative integer, and hence distinguishable from any valid character code. These macros may thus be efficiently implemented by using the argument as an index into a small array of attributes.

The standard itself has this to say:

The header <ctype.h> declares several functions useful for classifying and mapping characters. 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.

like image 85
paxdiablo Avatar answered Oct 10 '22 13:10

paxdiablo


When C was first invented, there was no compile-time checking of function arguments. If one called foo(bar,boz), and bar and boz were of type int, the compiler would push two int values on the stack, call foo, and hope it was expecting to get two int values. Since integer types smaller than int are promoted to int when evaluating expressions, C functions which were written prior to the invention of prototypes could not pass any smaller integer type.

like image 23
supercat Avatar answered Oct 10 '22 13:10

supercat