Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Tutorial - Wonder about `int i = *(int *)&s;`

Tags:

c

Working my way through a C tutorial

#include <stdio.h>

int main() {
  short s = 10;
  int i = *(int *)&s; // wonder about this
  printf("%i", i);
  return 0;
}

When I tell C that the address of s is an int, should it not read 4 bytes?

Starting from the left most side of 2 bytes of s. In which case is this not critically dangerous as I don't know what it is reading since the short only assigned 2 bytes?

Should this not crash for trying to access memory that I haven't assigned/belong-to-me?

like image 453
Mâtt Frëëman Avatar asked Sep 18 '11 16:09

Mâtt Frëëman


4 Answers

  1. Don't do that ever
  2. Throw away the tutorial if it teaches/preaches that.

As you pointed out it will read more bytes than that were actually allocated, so it reads off some garbage value from the memory not allocate by your variable.

In fact it is dangerous and it breaks the Strict Aliasing Rule[Detail below] and causes an Undefined Behavior.
The compiler should give you a warning like this.

warning: dereferencing type-punned pointer will break strict-aliasing rules

And you should always listen to your compiler when it cries out that warning.


[Detail]

Strict aliasing is an assumption, made by the C (or C++) compiler, that dereferencing pointers to objects of different types will never refer to the same memory location (i.e. alias each other.)

The exception to the rule is a char*, which is allowed to point to any type.

like image 89
Alok Save Avatar answered Nov 08 '22 08:11

Alok Save


First of all, never do this.

As to why it doesn't crash: since s is a local, it's allocated on the stack. If short and int have different sizes in your architecture (which is not a given), then you will probably end up reading a few more bytes from memory that's on the same memory page as the stack; so and there will be no access violation (even though you will read garbage).

Probably.

like image 43
Jon Avatar answered Nov 08 '22 08:11

Jon


This is dangerous and undefined behaviour, just as you said.

The reason why it doesn't crash on 32 (or 64) bit platforms is that most compilers allocate atleast 32 bits for each stack variable. This makes the access faster, but on e.g. 8 bit processor you would get garbage data in the upper bits instead.

like image 1
jpa Avatar answered Nov 08 '22 10:11

jpa


No it's not going to crash your program, however it is going to be reading a portion of other variables (or possibly garbage) on the stack. I don't know what tutorial you got this from, but that kind of code is scary.

like image 1
Chris Eberle Avatar answered Nov 08 '22 09:11

Chris Eberle