Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why char* can hold a single char in C?

Tags:

c

string

pointers

This might sound too crazy but I just had a thought. In C why

char *pc = 'H';      // single character
char *ps = "hello";  // a string

both are valid? I mean why a char* can hold/refer a character as well as a null terminated string?

Why there are no guard clause or compiler error generated for *pc as that char* is not holding a null terminated string?

I checked it in Ideone and don't get any warning.

like image 720
Anirban Nag 'tintinmj' Avatar asked Mar 19 '14 18:03

Anirban Nag 'tintinmj'


Video Answer


3 Answers

It can hold a char because there is an implicit conversion from char to char * (via int), and because sizeof(char *) >= sizeof(char). You shouldn't do this, though (technically it is undefined behavior because the literal numeric value of a character is not likely to be a valid pointer address to a char type).

And in many/most compilers, this does generate a warning:

$ gcc -otest test.c
test.c:5: warning: initialization makes pointer from integer without a cast
like image 87
TypeIA Avatar answered Sep 30 '22 21:09

TypeIA


char *pc = 'H';

The above statement defines pc of type char * which means it can hold the address of an object of type char. You are initializing it with the character H - a different type. Remember that a character literal is of type int and evaluates to its character code which in ASCII is 72. So, the above statement is equivalent to

char *pc = 72;

This is an illegal operation and compiler should warn you about it (in gcc, use the flag -Wall). You should not directly assign an address to a pointer because you don't know if you have access to the memory address. You should use the address of operator & to get the address of an object and then assign it to a pointer.

char *ps = "hello"; 

In the above statement, the string literal evaluates to a pointer to its first element. This address is assigned to ps which is of the same type, i.e., char *. However, string literals are read-only in C but are not const qualified (unlike in C++) and thus attempting to modify the string literal using the pointer ps would not result in compiler error but undefined behaviour and most likely program crash due to segfault. Therefore, you should define ps as a pointer to a const object -

const char *ps = "hello";
like image 34
ajay Avatar answered Sep 30 '22 19:09

ajay


In

char *pc = 'H';

'H' as an int will be casted to a char * and will be used to initialize pc, compiler should give a warning about this.

In

char *ps = "hello";

"hello" will evaluate to its base address, which will be used to initialize ps.

like image 44
Lee Duhem Avatar answered Sep 30 '22 20:09

Lee Duhem