Explicit cast when assigning pointers in C

pointer casting in c tutorial
how to cast a pointer to an integer in c
type casting pointers in c++
type casting in c
void pointer in c
c cast void pointer
c double cast
dynamic casting in c++

In C if I write the following code:

#include <stdio.h>

int main() {
        char c;    
        int* ip;
        char* cp;

        cp = &c;
        ip = cp;

        printf("%p %p %p %p\n", cp, ip, cp+1, ip+1);

        return 0;
}

I get a warning about not explicitly casting cp to ip. However, the code itself seems to work just fine. If c had address 1000 I get 1000 1000 1001 1004 as output.

My question is why is the explicit cast needed. Is it simply because the C standard doesn't state anything about implicit conversions of pointers (other than void*) or is there something else going on in the explicit cast?

warning about not explicitly casting cp to ip why is the explicit cast needed (?)

Pointers to int may have stricter alignment needs than char *. E.g. All int must begin on an even address, whereas a char * may be odd. Other issues apply too.

A cast tells "silly compiler, I know better and to just do the conversion - don't care if it causes a bus fault."

Tip: don't do it.

What are the rules for casting pointers in C?, There are no rules on casting pointers in C! The language lets you cast any pointer to any other pointer without comment. But the thing is: There is no data conversion or whatever done! Chapter 22: Pointers to Pointers:. One side point about pointers to pointers and memory allocation: although the void * type, as returned by malloc, is a "generic pointer," suitable for assigning to or from pointers of any type, the hypothetical type void ** is not a "generic pointer to pointer".

I get a warning about not explicitly casting cp to ip.

You aren't compiling with strict enough compiler settings then. If you wish to get an error upon C language violations, you'll need something like gcc -std=c11 -pedantic-errors or equivalent.

However, the code itself seems to work just fine.

char* and int* are not compatible pointer types. Your code is not fine as far as the C language is concerned - ip = cp; is a violation of the "simple assignment" rule. And so your code relies on undefined behavior and non-standard compiler extensions.

My question is why is the explicit cast needed. Is it simply because the C standard doesn't state anything about implicit conversions of pointers (other than void*) or is there something else going on in the explicit cast?

Specifically, because of the rules of how to use the assignment operator, stated at C17 6.5.16.1 Simple assignment, emphasis mine:

One of the following shall hold: /--/ - the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;

The same rule has exceptions for void* and null pointer constants.

Typecasting in C, If the type-checking system is overridden by an explicit cast or the pointer is Assigning an unaligned value to a pointer that references a type that needs to be​  Converting one datatype into another is known as type casting or, type-conversion. For example, if you want to store a 'long' value into a simple integer then you can type cast 'long' to 'int'. You can convert the values from one type to another explicitly using the cast operator as follows − (type_name) expression

Casting it basically just saying to the compiler "Trust me. I know what I'm doing." More often than not the programmer is wrong. If you only use casting only to suppress warnings, then you are doing something seriously wrong. And making an int* point at a char is just asking for trouble.

C has the nasty concept of undefined behavior which means that anything may happen, including the code working as it should. And that's the case here.

Here is an example of how it can go wrong:

#include <stdio.h>

struct myStruct {
        char a, b, c, d;
};

int main(void)
{
        struct myStruct s = { 'a', 'b', 'c', 'd' };
        int* p = &s.b;
        printf("%c %c %c %c\n", s.a, s.b, s.c, s.d);
        *p=42;
        printf("%c %c %c %c\n", s.a, s.b, s.c, s.d);
}

Output:

$ ./a.out 
a b c d
a *   

What has happened here is that because int is four bytes it will overwrite three other bytes when you are writing to s.b. Those are s.c, s.d and another byte we know nothing of. It's not hard to see that this can cause unwanted effects.

Use of Void pointers in C programming language, Type Conversions In C, operands of different types can be combined in one operation. Explicit casts avoid compiler warnings, and also signpost your program's type In the pointer arithmetic operations and assignment to iPtr (see also  (a) We define a pointer variable, (b) assign the address of a variable to a pointer and (c) finally access the value at the address available in the pointer variable. This is done by using unary operator * that returns the value of the variable located at the address specified by its operand.

TypeCasting in C: Implicit, Explicit with Example, The type casting of a pointer is actually a very valid use case in C, and does not have you dereference (that is, take the value-at-address of) the type-cast pointer, type to a pointer of another type (without an explicit cast) signal an oversight. Adding an explicit cast may help the compiler convert the integer value into a valid pointer. A common technique is to assign the integer to a volatile-qualified object of type intptr_t or uintptr_t and then assign the integer value to the pointer:

void pointer in C, C + + still lets you use casts to freely circumvent these rules . void * : The Generic Pointer Like C , C + + allows you to implicitly convert a pointer to a implicit conversion to void * : ok in C and C + + We can assign f , a Foo * , to v , a void *  Pointers in C/C++ with Examples Pointers are symbolic representation of addresses. They enable programs to simulate call-by-reference as well as to create and manipulate dynamic data structures.

EXP36-C. Do not cast pointers into more strictly , Implicit type casting means conversion of data types without losing its First of all, the c variable gets converted to integer, but the compiler  Assignment itself will give you unportable code. Depending on architecture, pointers to different types may have different representation and converting from one pointer to another will cause undefined behavior if the converted to pointer represen

Comments
  • @Bathsheba Strict aliasing only kicks in if the contents of ip is accessed though, which isn't the case here. However, in case of misalignment, there might be UB for that reason, even when not accessing the data. But then this code won't even compile cleanly in the first place, on any conforming compiler.
  • @Lundin: Yup, I'm confusing C and C++ again. I'm such a cabbage head. Still, your answer says it all. Have an upvote, and I'll clean up.
  • Here are many examples of why you shouldn't do this: google.com/search?q=sigbus+arm+site:stackoverflow.com "But it works on my x86 system!" doesn't make it correct.
  • @Lundin Agreed. Warnings do not always work - unfortunately
  • Thank you, this makes sense. I was not aware that memory allocations might have different alignment requirements for different data types.
  • @Samik Note that a int * and char * could even be of different bytes sizes. C supports many architectures, not only popular ones. printf("%p\n", ip); can readily fail without a cast. printf("%p\n", (void*) ip);
  • This is a great example. It would be worth an upvote if you explained why assigning 42 to *p produced the given result.
  • @LeeJenkins Fixed