92

My code is the following

int tmpCnt;  
if (name == "Dude")  
   tmpCnt++;  

Why is there an error "Use of unassigned local variable tmpCnt"?

I know I didn't explicitly initialize it, but due to Default Value Table a value type is initialized with 0 anyway. The reference also reminds me:

Remember that using uninitialized variables in C# is not allowed.

But why do I have to do it explicitly if it's already done by default? Wouldn't it gain performance if I wouldn't have to do it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
theknut
  • 2,533
  • 5
  • 26
  • 41
  • I have a local struct, never initialized, compiles with no errors. Today I created a different struct, treated identically, got "uninitialized local variable error". All its *members* were set to a value before use, but I could not first set it to null, since it was 'just' a struct. The struct that compiled contained only ints, bools and strings. The one that gave the error also contained DateTimes. "MyStructType myStruct = new MyStructType();" killed the error. Not the first time I've been bitten by missing something a few levels down. – MickeyfAgain_BeforeExitOfSO Jun 02 '16 at 19:14
  • Possible duplicate of [Why C# local variables must be initialized?](https://stackoverflow.com/questions/4182666/why-c-sharp-local-variables-must-be-initialized) –  Nov 12 '19 at 08:16

10 Answers10

164

Local variables aren't initialized. You have to manually initialize them.

Members are initialized, for example:

public class X
{
    private int _tmpCnt; // This WILL initialize to zero
    ...
}

But local variables are not:

public static void SomeMethod()
{
    int tmpCnt;  // This is not initialized and must be assigned before used.

    ...
}

So your code must be:

int tmpCnt = 0;  
if (name == "Dude")  
   tmpCnt++;  

So the long and the short of it is, members are initialized, locals are not. That is why you get the compiler error.

James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
  • 2
    @James: do you know if this is merely a compiler feature for preventing such a mistake, or if the C# compiler actually delays memory allocation for declared locals until assignment? (For example, in C++, using an unassigned variable is "ok" even though the value of such a variable is unpredictable.) – ybakos Mar 29 '12 at 17:34
  • 3
    Compiler feature to avoid the mistake. The memory (which of course is just a reference for reference types) for the local is allocated at the declaration. – James Michael Hare Mar 29 '12 at 17:38
  • 3
    To avoid what mistake? – Raikol Amaro May 10 '19 at 00:30
  • using newish `out var variable` syntax gives this warning too, I think this case is annoying – mkb Feb 19 '21 at 01:48
18

Default assignments apply to class members, but not to local variables. As Eric Lippert explained it in this answer, Microsoft could have initialized locals by default, but they choose not to do it because using an unassigned local is almost certainly a bug.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
9

The following categories of variables are classified as initially unassigned:

  • Instance variables of initially unassigned struct variables.
  • Output parameters, including the this variable of struct instance constructors.
  • Local variables , except those declared in a catch clause or a foreach statement.

The following categories of variables are classified as initially assigned:

  • Static variables.
  • Instance variables of class instances.
  • Instance variables of initially assigned struct variables.
  • Array elements.
  • Value parameters.
  • Reference parameters.
  • Variables declared in a catch clause or a foreach statement.
Joe
  • 80,724
  • 18
  • 127
  • 145
3

Local variables don't have a default value.

They have to be definitely assigned before you use them. It reduces the chance of using a variable you think you've given a sensible value to, when actually it's got some default value.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Damith
  • 62,401
  • 13
  • 102
  • 153
  • Wouldn't that be an argument for instance variables and class variables to not have default values either (they do have default values)? – Peter Mortensen Jan 07 '21 at 19:26
1

A very dummy mistake, but you can get this with a class too if you didn't instantiate it.

BankAccount account;
account.addMoney(5);

The above will produce the same error whereas:

class BankAccount
{
    int balance = 0;
    public void addMoney(int amount)
    {
        balance += amount;
    }
}

Do the following to eliminate the error:

BankAccount account = new BankAccount();
account.addMoney(5);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zar
  • 11,361
  • 14
  • 96
  • 178
1

The default value table only applies to initializing a variable.

Per the linked page, the following two methods of initialization are equivalent...

int x = 0;
int x = new int();

In your code, you merely defined the variable, but never initialized the object.

nabrond
  • 1,368
  • 8
  • 17
0
IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize

Assign value(_getCurrentHolidayList) inside the loop

foreach (HolidaySummaryList _holidayItem in _holidayDetailsList)
{
                            if (_holidayItem.CountryId == Countryid)
                                _getCurrentHolidayList = _holidayItem.Holiday;                                                   
}

After your are passing the local varibale to another method like below. It throw error(use of unassigned variable). eventhough nullable mentioned in time of decalration.

var cancelRescheduleCondition = GetHolidayDays(_item.ServiceDateFrom, _getCurrentHolidayList);

if you mentioned like below, It will not throw any error.

IEnumerable<DateTime?> _getCurrentHolidayList =null;
Ronika
  • 24
  • 2
0

See this thread concerning uninitialized bools, but it should answer your question.

Local variables are not initialized unless you call their constructors (new) or assign them a value.

Community
  • 1
  • 1
Msonic
  • 1,456
  • 15
  • 25
0

Local variables are not automatically initialized. That only happens with instance-level variables.

You need to explicitly initialize local variables if you want them to be initialized. In this case, (as the linked documentation explains) either by setting the value of 0 or using the new operator.

The code you've shown does indeed attempt to use the value of the variable tmpCnt before it is initialized to anything, and the compiler rightly warns about it.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

While value types have default values and can not be null, they also need to be explicitly initialized in order to be used. You can think of these two rules as side by side rules.

Value types can not be null → the compiler guarantees that. If you ask how, the error message you got is the answer. Once you call their constructors, they got initialized with their default values.

int tmpCnt; // Not accepted
int tmpCnt = new Int(); // Default value applied tmpCnt = 0
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sofian Hnaide
  • 2,284
  • 16
  • 13
  • 1
    Doesn't it depend more on the ***variable type*** rather than if it is a value type or reference type? Aren't ***instance variables*** of value types automatically initialised to the default value? – Peter Mortensen Jan 07 '21 at 19:15