0

I cannot understand why are pointer type casts necessary, as long as pointers point to an address and their type is important only when it comes to pointer arithmetic.

That is to say, if I encounter the next code snippet:

int a = 5; then both

char*b = (char*)&a; and int*c = (int*)&a

point to the very same memory location.

Indeed, when executing char*b = (char*)&a part of the memory contents may be lost, but this is due to the type of b is char* which can store only sizeof(char) bytes of memory, and this could be done implicitly.

pauk
  • 350
  • 4
  • 15
  • 2
    You can't just change pointer types and access memory any way you want to. [**What is the strict aliasing rule?**](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) There's a lot of bad code that violates that rule, and you're going to get told "But it works!" by those who don't understand the consequences of undefined behavior include ***appears*** to work. Because it will only "work" until it doesn't. For example: [**gcc, strict-aliasing, and horror stories**](https://stackoverflow.com/questions/2958633/gcc-strict-aliasing-and-horror-stories) – Andrew Henle Feb 04 '21 at 10:44
  • I see a cast as a message to the compiler: "I know I am doing something wrong, please don't complain about it and just do it." – mch Feb 04 '21 at 10:44
  • There's too many things to explain here. Pointer type compatibility, alignment, pointer sizes, pointer aliasing, representation of data types, endianess etc. – Lundin Feb 04 '21 at 10:57

3 Answers3

3

The pointer type is important when you dereference it, since it indicates how many bytes should be read or stored.

It's also important when you perform pointer arithmetic, since this is done in units of the size that the pointer points to.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

The type of the pointer is most important when you dereference the pointer.

The excerpt

char *b = (int*)&a;

is wrong because int * cannot be assigned to char *. You meant char *b = (char *)&a;. The C standard says you need an explicit cast because the types are not compatible. This is the "yeah yeah, I know what I am doing".

The excerpt

int*c = (int*)&a;

is right, but &a is already a pointer to an int, so the cast will do no conversion, therefore you can write it as int *c = &a;.

  • My bad, I was wrong, thus I edited my post so that the excerpt is char * b = (char *)&a; . Also, int *c = &a is correct, but I wanted to stress that from my point of view the only important thing related to cast consists of the size of the read bytes. – pauk Feb 04 '21 at 11:05
  • Furthermore it is always wrong to access part of a larger type with `char`, since it is a type which may or may not be signed, meaning that the sign bit if present might get set. The correct type to use is `unsigned char` or `uint8_t`. – Lundin Feb 04 '21 at 11:11
  • Now I understand that the compiler is very careful and tries to warn me that I may do something wrong, thus, I have to cast in order to tell the compiler that I know what "madness" I do. – pauk Feb 04 '21 at 11:11
  • Also, I expected to get a warning and not a compile error when passing "incompatible" pointer types. – pauk Feb 04 '21 at 11:59
  • Are you using a C or C++ compiler? They might have different "severity" changes between them. The incompatible pointer type is a constraint violation, there is no "expectations" whether it is a failure or "just a warning" - it is constraint violation in either case and your program is invalid under current standards. A compiler is allowed to **not reject an invalid program** for as long as it successfully compiles a valid program :P – Antti Haapala -- Слава Україні Feb 04 '21 at 14:19
1

as long as pointers point to an address and their type is important only when it comes to pointer arithmetic.

No, not only for pointer arithmetic. Its also important for accessing the data pointed by the pointer, the wrong way of accessing as in your example leads to improper results.

when executing charb = (int)&a part of the memory contents may be lost, but this is due to the type of b is char* which can store only sizeof(char) bytes of memory,

First of all, that is wrong to do (unless we really need to extract 1-byte out of 4-bytes)
Second, the application of pointer cast is mostly used w.r.t void*(void pointers) when passing data for a function which can handle many different type, best example is qsort

IrAM
  • 1,720
  • 5
  • 18