Reputation: 463
So, I am making a C program for my console interpreter to detect which type is it, then return it to typeret
and store the pointer into the void pointer retpoint
.
Now, what I am asking is not what is in the code, but rather why GCC optimizes this assignment in my function eval
. I want to know why GCC optimizes something that is actually important.
int eval(wchar_t *expr) {
// ....
if (expr[0] == L'\'' && expr[csize - 1] == L'\'') { // <-- Ignore this.
expr[csize - 1] = 0;
typeret = 0;
retpoint = (expr + 1);
} else if (strin(L".", expr)) { // <-- Ignore this.
typeret = 2;
} else {
typeret = 1;
tvar = _wtoi(expr); // <-- Here is the problem.
retpoint = &tvar;
}
return 0;
}
When I compile the code with the GCC command, gcc -Wsomewarning -o cim.exe cim.c -Os -s -ffunction-sections -fdata-sections -O3
, the assignment is not detected (even without -ffunction-sections
and -fdata-sections
, the assignment is not detected too).
But, when I change the code that involves around tvar
OR around _wtoi
, the assignment is not ignored. Here is the example code whereby the assignment is not ignored.
int eval(wchar_t *expr) {
int
tvar; // If I set tvar to N, then the assignment is still ignored (making tvar = N).
// ....
if (expr[0] == L'\'' && expr[csize - 1] == L'\'') { // <-- Ignore this.
expr[csize - 1] = 0;
typeret = 0;
retpoint = (expr + 1);
} else if (strin(L".", expr)) { // <-- Ignore this.
typeret = 2;
} else {
typeret = 1;
tvar = _wtoi(expr); // <-- Here is the problem.
wprintf(L"%d", tvar); // or wprintf(L"%d", _wtoi(expr);
retpoint = &tvar;
}
return 0;
}
Now, of course, if I use the gcc -o cim.exe cim.c
(without optimization), the first code works fine; however, the size is four times bigger than the optimized one.
Note
I am sure there is no undefined behavior in this program, and I am sure that I have given the data correctly.
The typeret
and retpoint
is a global data, whereas the tvar
is a local variable.
Edit
I forgot to mention that I used GCC version (tdm64-1) 4.9.2 in Windows 10.
Thanks in advance.
Upvotes: 0
Views: 121
Reputation: 57922
In your first example, the variable tvar
is not accessed, neither directly nor through the pointer retpoint
, between the assignment tvar = _wtoi(expr);
and when the function eval
returns, and after that the lifetime of tvar
ends because it is local. And you are only allowed to access tvar
during its lifetime. So the compiler has every right to optimize out the assignment because it cannot have any effect on a correct program.
If it does change the behavior of your program, then you probably have undefined behavior somewhere. Perhaps you are dereferencing the pointer retpoint
after eval
returns. That is definitely UB. In general, setting a global pointer to point to a local variable, and leaving it there after the function returns, is very suspicious.
Upvotes: 2