I have this snippet of code:
#include <stdio.h>
void optimization_headache()
{
int t = 11;
int l[1047] = {0};
int u_lu[23] = {0};
int u = 0;
l[0] = 0;
l[1] = 0;
do {
u++;
//printf("Incrementing u, now u is %d\n", u);
u_lu[u + 1] = u - l[u + 1];
} while ((u < t * 2) && (l[u + 1] <= t));
printf("u = %d, l[u] = %d, t = %d, u_lu[u] = %d\n", u, l[u], t, u_lu[u]);
}
int main()
{
optimization_headache();
return 0;
}
Upon compiling with optimizations off ($ gcc -Wall -Wextra -O0 main.c
), the code compiles, and I get the following output:
u = 22, l[u] = 0, t = 11, u_lu[u] = 21
When I compile with full optimizations ($ gcc -Wall -Wextra -O3 main.c
), the program hangs, and top indicates it's using 100% of my CPU. It must be running forever in the do while loop.
I can get the code to compile with full optimizations and run correctly by changing one or all of the following:
1) If I comment out l[0] = 0; l[1] = 0;
.
2) If I make u
a volatile int
instead.
3) If I uncomment the printf
inside the do while loop.
So obviously, I don't understand what the optimizations are doing, and why it changes the behavior of my program. I could just choose one of the above solutions to get it to run, but I really really want to know what's going on here. It's so weird to me.
(The C++ tag might not be appropriate, but I see the same behavior using g++ as well)
Code optimization is any method of code modification to improve code quality and efficiency. A program may be optimized so that it becomes a smaller size, consumes less memory, executes more rapidly, or performs fewer input/output operations.
Optimization is a program transformation technique, which tries to improve the code by making it consume less resources (i.e. CPU, Memory) and deliver high speed. In optimization, high-level general programming constructs are replaced by very efficient low-level programming codes.
As pointed out in the comments, this could happen if you invokes undefined behavior.
In your case, this is the relevant part:
int t = 11;
int u_lu[23] = {0};
do {
u++;
u_lu[u + 1] = u - l[u + 1];
} while ((u < t * 2) /*...*/);
The loop runs while u
is smaller then 22, so it can become 21. But inside the loop, you increment u
twice and writing to u_lu[23]
. This is one more then allocated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With