1

To understand strict-aliasing and the usage of restrict keyword, I am trying the program shown below. In this case, same memory location is referenced by two pointers. Hence without user explicitly telling, compiler can't do any optimization (i.e. without using restrict keyword). Hence my understanding was that without restrict keyword, output of the program will be 40 and with 'restrict' output will be 30 (as 'a' does not need to be read from memory after "*b += *a"). However even with restrict, output is 40. why the optimization is not happening?

I am following "What is the strict aliasing rule?" for understanding.

#include <stdio.h>

void merge_two_ints(int * restrict a, int * restrict b) {
  *b += *a;
  *a += *b;
}

int
main(void)
{
    int x = 10;
    int *a = &x;
    int *b = &x;
    merge_two_ints(a, b);
    printf("%d\n", x);
    return 0;
}

bash-3.2$ gcc -Wall -O3 -fstrict-aliasing -std=c99 strict_alias2.c

bash-3.2$ ./a.out 40

curiousguy
  • 8,038
  • 2
  • 40
  • 58
NeilB
  • 347
  • 2
  • 16
  • 4
    *Hence my understanding was that without restrict keyword, output of the program will be 40 and with 'restrict' output will be 30* - No. With `restrict` it will be undefined. – Eugene Sh. Jan 16 '18 at 20:53
  • @EugeneSh.By using restrict, are we not telling compiler that a and b are not pointing towards same memory? so it can optimize without worry? – NeilB Jan 16 '18 at 20:57
  • 3
    It can optimize but does not have to. You are promising the compiler something, but then you break your promise. These things are not working well. – Eugene Sh. Jan 16 '18 at 20:58
  • You cheat your compiler so what you expect as a result. It the perfect axample if the language abuse, C language allows a lot comparing to another languages. But do not worry too much. All beginners go through it. – 0___________ Jan 16 '18 at 21:10
  • 1
    BTW, it has little (like nothing) to do with *strict aliasing*. – Eugene Sh. Jan 16 '18 at 21:13

1 Answers1

4

You observe:

In this case, same memory location is referenced by two pointers. [...] my understanding was that without restrict keyword, output of the program will be 40 and with 'restrict' output will be 30 (as 'a' does not need to be read from memory after "*b += *a").

But your expectation is directly contrary to the C standard, which specifies:

The intended use of the restrict qualifier [...] is to promote optimization, and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning (i.e., observable behavior).

(C2011 6.7.3/8; emphasis added)

Furthermore, 6.7.3/8 also says,

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.

and without going into the details, 6.7.3.1 explicitly specifies that when its provisions are not satisfied by a given program, the behavior is undefined. Your program triggers this provision, and you are anticipating a particular manifestation of the resulting undefined behavior. Nothing in the C language justifies that.

However even with restrict, output is 40. why the optimization is not happening?

The C language never requires either optimization in general or any specific optimization to be performed.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157