I have written in the past that I sometimes miss the Borland C compiler when it comes down to warnings, because there was at least one that it really was interesting and that GCC lacks: warning about variables whose value is set and never used.
The problem is for instance in this example C code:
int foo(int n) {
int t = 123;
t = bar(n);
return t+n;
}
As you can guess, that t = 123
part is totally useless since t is replaced right afterward. Obviously without optimisation, GCC will emit the assignment anyway:
foo:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $32, %rsp
.LCFI2:
movl %edi, -20(%rbp)
movl $123, -4(%rbp)
movl -20(%rbp), %edi
movl $0, %eax
call bar
movl %eax, -4(%rbp)
movl -20(%rbp), %edx
movl -4(%rbp), %eax
addl %edx, %eax
leave
ret
But the assignment will rightfully disappear once optimisations are turned on, even at just the first level:
foo:
.LFB2:
pushq %rbx
.LCFI0:
movl %edi, %ebx
movl $0, %eax
call bar
leal (%rbx,%rax), %eax
popq %rbx
ret
This is all nice and fine but the problem is that GCC does not warn even if it does remove the variable. But it’s not the only one, even Sun Studio Express and the Intel C Compiler don’t warn about such a case. Interestingly enough, Sun Studio’s lint tool in “enhanced” mode does report the issue:
assigned value never used
t defined at test-ssa.c(2) :: set at test-ssa.c(2) :: reset at test-ssa.c(4)
too bad that autotools don’t integrate lint-like tools too easily (but maybe I can tie it in the FFmpeg buildsystem at least…).
Why am I so upset about this particular warning missing, you ask? Because it should be quite easy to implement considering that each compiler is most likely using SSA form for optimisation scans. And in SSA form, it’s trivial to see the code from before this way:
int foo(int n) {
int t1 = 123;
int t2 = bar(n);
return t2+n;
}
and notice that t1 is unused in the whole function. Indeed, it’s what the compiler already does, to optimise out the assignment, the problem is: it just does not warn you that’s what it’s doing. Sincerely, how difficult could it be for a GCC hacker to add that warning? — I’m sure I wouldn’t be able to myself, since I don’t know GCC well enough, and it’s likely a mess, but it doesn’t sound like a difficult warning to implement, to me.
> that GCC lacks: warning about variables whose value is set and never usedIt is just not enabled by default, try to compile this example with -Wall -Wextra, you get this:main.c: In function ‘foo’:main.c:8: warning: unused variable ‘t1’main.c: At top level:main.c:14: warning: unused parameter ‘argc’main.c:14: warning: unused parameter ‘argv’
Err no, what you tried to build was the SSA form-alike version, and yes in that case it _does_ warn you, but if you look at the non-expanded form at the top of the sources, it doesn’t warn about it.
Oh, you’re right, I’ve tried the wrong example ^^
I did not find the link to the bug report.
You just need -O2. Without O2, data flow optimization isn’t performed. DFO is obviously necessary to detect this.
NOTE: gcc 4.6 (just released) now detects such write-only variables with -Wunused-but-set-variable.