Raman
Raman

Reputation: 2785

Using volatile qualifier suppresses compiler warning

Today I was reviewing a guys's code where he had declared a variable volatile. On asking about it, he told it produces weird behaviour on some systems.

On removing volatile and compiling, it was producing this compiler warning

iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]

The code was very much similar to the below code, array being accessed out of bound. Since he was using a different codebase where Makefile was different, this warning was not produced on his system.

int a[4]={1,2,3,4};
int i;   //when declared volatile int i, doesn't produce warning
i=0;
while(i<5) {
    printf("%d\t", a[i]);    //a[4] will invoke undefined behavior
    i+=2;   
}

Now, I'm unable to figure out two things:

  1. Which exact gcc flags should I enable to get this warning?
  2. Why declaring i as volatile is suppressing that warning?

Upvotes: 3

Views: 242

Answers (3)

Tim Randall
Tim Randall

Reputation: 4145

When aggressive loop optimization sees the following code...

int i;
i=0;
while(i<5) {
    printf("%d\t", a[i]);
    i+=2;   
}

... it's going to use a technique called "loop unrolling" to rewrite it like this...

printf("%d\t", a[0]);
printf("%d\t", a[2]);
printf("%d\t", a[4]);

Problem! Iterations 0 and 1 are fine, but iteration 2 will perform an out-of-bounds array access, invoking undefined behavior. That's why you got the warning you did.

Declaring i to be volatile prevents the compiler from doing this optimization (because it can't be sure that another process isn't modifying the value of i during loop execution), so it has to leave the code as it was. You still have the undefined behavior, it's just that the compiler doesn't warn you about it. All in all, a terrible "fix" from your co-worker.

Upvotes: 4

Adam
Adam

Reputation: 17329

The undefined behavior you have is that your loop allows i=4, which will read past the end of the array. This is noticed by the loop optimizer, but of course it's a problem regardless of optimization.

volatile tells the compiler that the value of i can be changed from outside this code. The practical effect of this is that the compiler cannot do optimizations that depend on assuming the value of i. That turns off the optimization that noticed your problem.

Using volatile solely to bypass the warning is terrible practice. Instead change the while condition to while (i < 4).

Upvotes: 2

melpomene
melpomene

Reputation: 85757

  1. The warning tells you which flag enables it: -Waggressive-loop-optimizations
  2. Declaring a variable volatile means the compiler must assume that things outside of the compiler's control may inspect and modify the variable. Therefore it cannot assume that i will ever take the value 4 (or that i += 2 will always add 2 to i's value, etc).

Upvotes: 1

Related Questions