Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not casting pointers in C can cause problems?

Yesterday I was in class, and at some point the instructor was talking about C code. He said:

What is the purpose of making a pointer cast in C? The only purpose is to make the compiler interpret correctly the pointer operations (for example, adding an int pointer will result in a different offset than adding a char pointer). Apart from that, there is no difference: all pointers are represented the same way in memory, regardless if the pointer is pointing to an int value, a char value, a short value, or whatever. So, casting a pointer will not modify anything in the memory, it will just help the programmer with operations more related with the pointer-type he is dealing with.

However, I have read, specially here in Stack Overflow, that this is not 100% true. I have read that in some weird machines, pointers for different types can be stored in different ways in memory. In this case, not changing the pointer to the correct type could cause problems if the code is compiled to this kind of machine.

Basically, this is the kind of code I'm talking about. Consider the code below:

int* int_pointer;
char* char_pointer;
int_pointer = malloc(sizeof(int));
*int_pointer = 4;

And now two options:

1.

char_pointer = (char *)int_pointer;

2.

char_pointer = int_pointer;

The code on case 2 could became a problem? Making the cast (case 1) would eventually change the pointer format in memory (if yes, could you give an example of machine?)?

Thanks

like image 633
felipeek Avatar asked May 13 '15 20:05

felipeek


People also ask

What does casting a pointer do?

In the C language, casting is a construct to view a data object temporarily as another data type. When you cast pointers, especially for non-data object pointers, consider the following characteristics and constraints: You can cast a pointer to another pointer of the same IBM® i pointer type.

Does casting a pointer change its value?

A cast does not change the value of an object. While technically correct, your answer is misleading. Casting a pointer to a class instance may return a different pointer address than the casted pointer contains.

What happens when casting in C?

Type casting refers to changing an variable of one data type into another. The compiler will automatically change one type of data into another if it makes sense. For instance, if you assign an integer value to a floating-point variable, the compiler will convert the int to a float.

Is casting malloc necessary?

In C, you don't need to cast the return value of malloc . The pointer to void returned by malloc is automagically converted to the correct type. However, if you want your code to compile with a C++ compiler, a cast is needed.


2 Answers

Not casting pointers in C can cause problems?

There is no implicit conversion between pointer types in C (as there are for example between arithmetic types) - with the exception with void * type. It means C requires you to cast if you want to convert a pointer to another pointer type (except for void *). If you fail to do so an implementation is required to issue a diagnostic message and is allowed to fail the translation.

Some compilers are nice enough (or pervert enough) to not require the cast. They usually behave as if you explicitly put the cast.

 char *p = NULL;
 int *q =  NULL;

 p = q;  // not valid in C

In summary you should always put the cast when converting pointers to pointers for portability reasons.

EDIT:

Outside portability, an example where not casting can cause you real problems is for example with variadic functions. Let's assume an implementation where the size of char * is larger than the size of int *. Let's say the function expects the type of one argument to be char *. If you want to pass an argument of int *, you then have to cast it to char *. If you don't cast it, when the function will access the char * object some bits of the object will have an indeterminate value and the bevahior will be undefined.

A somewhat close example is with printf, if a user fails to cast to void * the argument for the p conversion specifier, C says it invokes undefined behavior.

like image 61
ouah Avatar answered Sep 23 '22 02:09

ouah


What your instructor said about all pointer types sharing the same representation is generally true for real-life implementations of C language.

However, it is not true from the point of view of abstract C language itself. C language guarantees that

  1. char * pointers are represented in the same way as void * pointers.
  2. Pointers to a qualified version of type T (const, volatile, restrict) are represented in the same way as pointers to unqualified T.
  3. Pointers to all struct types are represented identically.
  4. Pointers to all union types are represented identically.

That is all. No other guarantees exist. Which means that as far as the language itself is concerned, int * pointer has different representation from double * pointer. And pointer to struct S is represented differently from pointer to union U.

However, your example with char_pointer and int_pointer, as presented, is not exactly illustrative. The char_pointer = int_pointer; assignment is simply invalid (as in "does not compile"). Language does not support implicit conversions between incompatible pointer types. Such conversions always require an explicit cast operator.

like image 32
AnT Avatar answered Sep 20 '22 02:09

AnT