Variables assigned and never used

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.

Exit mobile version