Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this pointer aliasing work?

https://kukuruku.co/post/i-do-not-know-c/

Problem #7:

#include <stdio.h>
void f(int *i, long *l)
{
  printf("1. v=%ld\n", *l); /* (1) */
  *i = 11;                  /* (2) */
  printf("2. v=%ld\n", *l); /* (3) */
}
int main()
{
  long a = 10;
  f((int *) &a, &a);
  printf("3. v=%ld\n", a);
  return 0;
}

Output on two different compilers on a little endian system is:

1. v=10    2. v=11    3. v=11
1. v=10    2. v=10    3. v=11

How is the second result possible ? I didn't quite get how the explanation that explains the result by referring to strict aliasing. Does the compiler ignore the line (2) totally ?

like image 654
Zoso Avatar asked Aug 29 '26 02:08

Zoso


1 Answers

Quoting Wikipedia:

In C or C++, as mandated by the strict aliasing rule, pointer arguments in a function are assumed to not alias if they point to fundamentally different types, except for char* and void*, which may alias to any other type. Some compilers allow the strict aliasing rule to be turned off, so that any pointer argument may alias any other pointer arguments. In this case, the compiler must assume that any accesses through these pointers can alias. This can prevent some optimizations from being made.

This is where the rule is violated:

f((int *) &a, &a);
    ^ aliasing to different type (a is 'long')
              ^ passing the same variable with different type

The problem is that assuming strict aliasing rules, first and second argument of the function point to another location because these are of different types. That is why author explains:

Therefore, we can assume that any long has not changed.

And in here: printf("2. v=%ld\n", *l); a long value is dereferenced.

That is why this part (2) is undefined behaviour on both compilers.

like image 153
syntagma Avatar answered Aug 31 '26 17:08

syntagma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!