C# pitfall: local variables returned must be initialized to somevalue first

  • Thread starter Thread starter raylopez99
  • Start date Start date
R

raylopez99

Beware this newbie trap:

private bool myFunction (Myenum X)
{
bool local_bool; //this will not compile; you need to do this first:
bool local_bool = true;

switch (X) {

case 1:
local_bool = true;
break;

case 2:
local_bool=false;
break;
}

return local_bool;

}

This will not compile. You need to add a 'temporary' actual value for
it to compile, see the comment // above

RL

Hahahaha! You fed the troll! Eh, paranoid Marc and Goran? Koo-koo!
 
It won't compile because the compiler thinks that there is no guarantee that
one of the cases in the switch will be executed. If you add a default that
sets some value for local_bool, it will compile without the initializer on
the definition.
Also, if _all_ the possible values of an enum are covered by a switch
statement, it will compile. The compiler wants it to be _certain_ that that
variable is initialized before it's used.
 
raylopez99 wrote:

<snipped>


Only a newbie would post something like that.
Beware this newbie trap:
Hahahaha! You fed the troll! Eh, paranoid Marc and Goran? Koo-koo!

What is wrong with you? You seem to be two years old. Is it because of
that Spanish blood in you that you act like a hot head pistol? Or could
it be that you hang out in the cesspool Linux.Advocacy?
 
Beware this newbie trap:

private bool myFunction (Myenum X)
{
bool local_bool; //this will not compile; you need to do this first:
bool local_bool = true;

switch (X) {

case 1:
local_bool = true;
break;

case 2:
local_bool=false;
break;
}

return local_bool;

}

This will not compile. You need to add a 'temporary' actual value for
it to compile, see the comment // above
What you describe as a 'temporary' value isn't temporary if the value
of Myenum X is not one or two. Leave the switch out and the method
body is...

bool local_bool;
return local_bool;

What value do you believe the method should return?

regards
A.G.
 
Arthur Parker said:
Also, if _all_ the possible values of an enum are covered by a switch
statement, it will compile. The compiler wants it to be _certain_ that
that
variable is initialized before it's used.

Actually, no, it won't, because range of allowed values for any enum type is
exactly the same as for its underlying integer type - it just so happens
that some of enum values are named, and others have to be obtained by
casting a plain integer value to enum type. Consider:

enum FooBar { Foo, Bar }

void Baz(FooBar x)
{
int y;
switch (x)
{
case FooBar.Foo: y = 0; break;
case FooBar.Bar: y = 1; break;
}
Console.WriteLine(x); // use of unassigned local variable ...
}

// ... because the caller can always do this:
Bar((FooBar)123);
 
First, I strongly recommend you simply ignore RL...
Also, if _all_ the possible values of an enum are covered by a switch
statement, it will compile.

I doubt it would; first this would mean every possible value of the
underlying data type [such as int] (enum values are not validated) - and
second, it doesn't even do this for "bool" - so I doubt it does it for
enum.

I can't see anything in the rules for definite assignment that would
make it care about all possible values being covered.

Marc
 
Actually, no, it won't, because range of allowed values for any enum typeis
exactly the same as for its underlying integer type - it just so happens
that some of enum values are named, and others have to be obtained by
casting a plain integer value to enum type. Consider:

    enum FooBar { Foo, Bar }

    void Baz(FooBar x)
    {
        int y;
        switch (x)
        {
            case FooBar.Foo: y = 0; break;
            case FooBar.Bar: y = 1; break;
        }
        Console.WriteLine(x); // use of unassigned local variable...
    }

    // ... because the caller can always do this:
    Bar((FooBar)123);

Pavel meant this, I think:
...
}
Console.WriteLine(y); // use of unassigned local variable
"y" ...
}
...
 
private bool MyFunction(MyEnum x)
{
switch (X)
{
case 1:
return true;

default:
return false;
}
}
 
What you describe as a 'temporary' value isn't temporary if the value
of Myenum X is not one or two. Leave the switch out and the method
body is...

        bool local_bool;
        return local_bool;

What value do you believe the method should return?

The one in the case statement.

Put another way: this would work:
//
private bool MyFunction(MyEnum x)
{
switch (X)
{
case 1:
return true;
default:
return false;
}
//

And so would this (I think, but I haven't tried it):

private bool myFunction (Myenum X)
{

bool local_bool = new bool(); //I think this will work and avoid
having to initialize the local_bool to something

switch (X) {
case 1:
local_bool = true;
break;
case 2:
local_bool=false;
break;
}

return local_bool;
}


So why doesn't my original post work? Oh well, there's an easy
workaround, which as I said in the OP is to add a fake value for
local_bool at the beginning. BTW the same thing used to happen in C++
for references--you had to 'initialize' references (&myRef = Object;)
to an actual instantiated object before anything with a reference
would compile. We've come a long way in C# since then, but vestiges
remain.

RL
 
The one in the case statement.
There is no case statement in the snippet above or the method below.
private bool MyFunction(MyEnum x)
{
        bool local_bool;
        return local_bool;
}
What value do you expect the method to return?
Put another way: this would work:
//
private bool MyFunction(MyEnum x)
{
switch (X)
{
case 1:
return true;
default:
return false;
}
//
Yes this works because the value to be returned is initialized before
the value is returned. Your original example contained a switch with
no default case. Change default : to case 2: and the code won't
compile.
And so would this (I think, but I haven't tried it):

private bool myFunction (Myenum X)
{

bool local_bool = new bool(); //I think this will work and avoid
having to initialize the local_bool to something
You think it will work? Do you not understand what the line
bool local_bool = new bool();
does? You are initializing a local variable while your supposed intent
is to avoid initializing a local variable.

- snip -
So why doesn't my original post work?
Because it is bad code. within the scope of your example the return
value may not be initialized.
Oh well, there's an easy
workaround, which as I said in the OP is to add a fake value for
local_bool at the beginning.
Yep, that is some genius stuff alright. You must be the smartest guy
at your keyboard.

regards
A.G.
 
Change default : to case 2: and the code won't
compile.

And why is that, Einstein?
You think it will work? Do you not understand what the line
        bool local_bool = new bool();
does? You are initializing a local variable while your supposed intent
is to avoid initializing a local variable.  

No. You don't know the difference between stack and heap. We are
talking about stack (non-new) variables not heap. I mentioned it
because changing the variable from stack to heap works, and my
question (implicitly) is why it won't do the same for stack variables.
Yep, that is some genius stuff alright. You must be the smartest guy
at your keyboard.

At least I can qualify for that honor. You are the dumbest guy, at
your keyboard.

RL
 
Back
Top