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.

6 thoughts on “Variables assigned and never used

  1. > 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’

    Like

  2. 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.

    Like

  3. You just need -O2. Without O2, data flow optimization isn’t performed. DFO is obviously necessary to detect this.

    Like

  4. NOTE: gcc 4.6 (just released) now detects such write-only variables with -Wunused-but-set-variable.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s