Why is no warning given for this unused variable?

2019-01-15 12:43发布

When compiling the following program in VS2010, VS2008 or MonoDevelop on Windows, I get warning CS0219, "The variable 'y' is assigned but its value is never used".

namespace Problem
{
    public class Program
    {        
        private static void Main(string[] args)
        {
            object x = new object();
            int y = 0;
        }
    }
}

Why is there no warning for x when compiling in Visual Studio?

Interestingly, I do get CS0219 warnings for x and y when compiling in MonoDevelop on Mac OS X.

6条回答
Animai°情兽
2楼-- · 2019-01-15 13:23

I could be off here, but I think it's because y is only set, whereas x is instantiated to something non-trivial - the instantiation could involve separate actions in the New() method, and since instantiating the variable could have side-effects, it's not considered unused. In your case it's just a base object(), so there's no impact, but perhaps the compiler isn't smart enough to tell the difference.

With y, on the other hand, there are no side-effects to the instantiation, so it's considered unused - the application's code path would be unchanged if it were removed entirely.

查看更多
We Are One
3楼-- · 2019-01-15 13:24

It could be that since x is a reference type, and is thus stored on the heap, that it would prevent garbage collection of that object until x goes out of scope.

for example:

void main(string[] args)
{
    object x = new object();
    while (true)
    {
        // some threading stuff
        // x is never garbage collected
    }
}

In contrast to:

void main(string[] args)
{
    new object();
    while (true)
    {
        // some threading stuff
        // the unreferenced object IS garbage collected
    }
}
查看更多
狗以群分
4楼-- · 2019-01-15 13:30

Eclipse will consider the case unused.

查看更多
【Aperson】
5楼-- · 2019-01-15 13:34

It turns out that this warning is suppressed when the right-hand-side of the assignment operation is not a compile-time constant.

A since-deleted post on Microsoft's Visual Studio feedback site explained that it's because they had lots of complaints from people who were assigning variables purely so they could see what a method call returned during debugging, and found the warning irritating:

The suppression of the "assigned but never used" warning in this case was motivated by feedback from users who do this:

int Blah(){
    // blah
    BlahBlah(x, y, z)
    // blah
    // blah
}

"Hey," says the user while debugging, "I wonder what BlahBlah is returning?" But there is no easy way to examine the return value in the debugger, so users very frequently do this:

int Blah()
{
    // blah
    int temp = BlahBlah(x, y, z)
    // blah
    // blah
}

and then use the locals or watch window to examine temp. The temp is never used anywhere else in the function, so it produced an irritating "assigned but not read" warning.

I think this is a bit of a shame since:

  1. I actually find these warnings helpful when they are given in MonoDevelop.
  2. Anyone can suppress the warning themselves (admittedly they'd also be suppressing the ones for unused compile-time constant assignments - maybe there should be a separate warning for that?).

Anyway, I understand that you can't please everyone.

查看更多
Evening l夕情丶
6楼-- · 2019-01-15 13:40

My hunch is that, being x a reference type the compiler does not show any warning since the constructor may be performing some operation that may very well be "meaningful"; in contrast, y being a value type whose value only gets assigned to but never used, it's easy for the compiler to tell you that there's no point in doing this if you are not going to reference it down the line.

查看更多
Fickle 薄情
7楼-- · 2019-01-15 13:42

Resharper will also warn you that x is unused.

查看更多
登录 后发表回答