Home All Groups Group Topic Archive Search About

Initial value of uninitialized variables in C# (reference type)

Author
23 May 2006 6:16 AM
Vagif Abilov
After porting some code from .NET 1.1 to .NET 2.0 I got a problem with some
static variables (reference types) that were not set to null. I received the
following comment on it:

"only in vb.net are un-initialozed variables set to null. in c# you need to
do it yourself, as the compiler doesn't emit and initalation code you don't
include. its a bug in your code. its just luck it worked in 1.1"

I must say that if this it true, it means I was completely misunderstanding
the way .NET initialized reference type instances. I thought they are set to
null, i.e. the following declarations of a1 and a2 are equal:

class A
{
....
}

class B
{
....
    A a1 = null;
    A a2;
}

If they are not, then what a2 is initialized to?

TIA
Vagif Abilov
Oslo Norway

Author
23 May 2006 8:04 AM
Dmytro Lapshyn [MVP]
Hi Vagif,

If an analogy with C++ is valid here, a2 is "initialized" to whatever
contained in the heap at the memory location designated to store the "a2"
member's value.

But actually I have always assumed that the a1 and a2 declarations are
equal - it's just probably I don't do any .NET 2.0 programming nowadays :-)

Show quote
"Vagif Abilov" <va***@online.no> wrote in message
news:ODwV7BjfGHA.2032@TK2MSFTNGP02.phx.gbl...
> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with
> some static variables (reference types) that were not set to null. I
> received the following comment on it:
>
> "only in vb.net are un-initialozed variables set to null. in c# you need
> to
> do it yourself, as the compiler doesn't emit and initalation code you
> don't
> include. its a bug in your code. its just luck it worked in 1.1"
>
> I must say that if this it true, it means I was completely
> misunderstanding the way .NET initialized reference type instances. I
> thought they are set to null, i.e. the following declarations of a1 and a2
> are equal:
>
> class A
> {
> ...
> }
>
> class B
> {
> ...
>    A a1 = null;
>    A a2;
> }
>
> If they are not, then what a2 is initialized to?
>
> TIA
> Vagif Abilov
> Oslo Norway
>
Author
23 May 2006 8:14 AM
Vagif Abilov
"If an analogy with C++ is valid here, a2 is "initialized" to whatever
contained in the heap at the memory location designated to store the "a2"
member's value."

It is hard to believe for me that C# drags this way of initializing objects
from C++. Hope not! Isn't predictable object state part of managed code
phylosophy?

Vagif



Show quote
"Dmytro Lapshyn [MVP]" <x-code@no-spam-please.hotpop.com> wrote in message
news:OrLN19jfGHA.1320@TK2MSFTNGP04.phx.gbl...
> Hi Vagif,
>
> If an analogy with C++ is valid here, a2 is "initialized" to whatever
> contained in the heap at the memory location designated to store the "a2"
> member's value.
>
> But actually I have always assumed that the a1 and a2 declarations are
> equal - it's just probably I don't do any .NET 2.0 programming nowadays
> :-)
>
> "Vagif Abilov" <va***@online.no> wrote in message
> news:ODwV7BjfGHA.2032@TK2MSFTNGP02.phx.gbl...
>> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with
>> some static variables (reference types) that were not set to null. I
>> received the following comment on it:
>>
>> "only in vb.net are un-initialozed variables set to null. in c# you need
>> to
>> do it yourself, as the compiler doesn't emit and initalation code you
>> don't
>> include. its a bug in your code. its just luck it worked in 1.1"
>>
>> I must say that if this it true, it means I was completely
>> misunderstanding the way .NET initialized reference type instances. I
>> thought they are set to null, i.e. the following declarations of a1 and
>> a2 are equal:
>>
>> class A
>> {
>> ...
>> }
>>
>> class B
>> {
>> ...
>>    A a1 = null;
>>    A a2;
>> }
>>
>> If they are not, then what a2 is initialized to?
>>
>> TIA
>> Vagif Abilov
>> Oslo Norway
>>
>
Author
23 May 2006 8:26 AM
Göran_Andersson
The a2 member variable in your example will be initialized to null.


From the article "Getting Started with C#":
http://www.samspublishing.com/articles/article.asp?p=23211&seqNum=8&rl=1

"Default initialization rules depend upon where a variable is declared
in a program. For the purposes of default initialization, there are two
types of variables — local variables and class variables. Variables are
initialized based upon whether they're class variables or local variables.

Local variables are uninitialized." ... "If a variable is declared
within a method, it is considered to be a local variable.

This is different from class variables, which are declared as class
members." ... "Class variables are initialized to default values if a
program's code does not explicitly initialize them."


From the article "C# - Static Members":
http://www.csharphelp.com/archives/archive148.html

"When we declare a static field inside a class, it can be initialized
with a value" ... "All un-initialized static fields automatically get
initialized to their default values when the class is loaded first time."


Vagif Abilov wrote:
Show quote
> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with some
> static variables (reference types) that were not set to null. I received the
> following comment on it:
>
> "only in vb.net are un-initialozed variables set to null. in c# you need to
> do it yourself, as the compiler doesn't emit and initalation code you don't
> include. its a bug in your code. its just luck it worked in 1.1"
>
> I must say that if this it true, it means I was completely misunderstanding
> the way .NET initialized reference type instances. I thought they are set to
> null, i.e. the following declarations of a1 and a2 are equal:
>
> class A
> {
> ...
> }
>
> class B
> {
> ...
>     A a1 = null;
>     A a2;
> }
>
> If they are not, then what a2 is initialized to?
>
> TIA
> Vagif Abilov
> Oslo Norway
>
Author
23 May 2006 8:37 AM
Vagif Abilov
I have an example with the following behavior:

a) Member variables a1 and a2 are static
b) In non-Web projects there is no difference between them
c) In Web project a2 is set to non-null value!

I am trying to extract a small part of reproducible code.

Vagif

Show quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:Ov7kjKkfGHA.4304@TK2MSFTNGP05.phx.gbl...
> The a2 member variable in your example will be initialized to null.
>
>
> From the article "Getting Started with C#":
> http://www.samspublishing.com/articles/article.asp?p=23211&seqNum=8&rl=1
>
> "Default initialization rules depend upon where a variable is declared in
> a program. For the purposes of default initialization, there are two types
> of variables — local variables and class variables. Variables are
> initialized based upon whether they're class variables or local variables.
>
> Local variables are uninitialized." ... "If a variable is declared within
> a method, it is considered to be a local variable.
>
> This is different from class variables, which are declared as class
> members." ... "Class variables are initialized to default values if a
> program's code does not explicitly initialize them."
>
>
> From the article "C# - Static Members":
> http://www.csharphelp.com/archives/archive148.html
>
> "When we declare a static field inside a class, it can be initialized with
> a value" ... "All un-initialized static fields automatically get
> initialized to their default values when the class is loaded first time."
>
>
> Vagif Abilov wrote:
>> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with
>> some static variables (reference types) that were not set to null. I
>> received the following comment on it:
>>
>> "only in vb.net are un-initialozed variables set to null. in c# you need
>> to
>> do it yourself, as the compiler doesn't emit and initalation code you
>> don't
>> include. its a bug in your code. its just luck it worked in 1.1"
>>
>> I must say that if this it true, it means I was completely
>> misunderstanding the way .NET initialized reference type instances. I
>> thought they are set to null, i.e. the following declarations of a1 and
>> a2 are equal:
>>
>> class A
>> {
>> ...
>> }
>>
>> class B
>> {
>> ...
>>     A a1 = null;
>>     A a2;
>> }
>>
>> If they are not, then what a2 is initialized to?
>>
>> TIA
>> Vagif Abilov
>> Oslo Norway
Author
23 May 2006 10:26 AM
Vagif Abilov
Actually this is what happenned. Here's a sample code.

I made a simlpe Web site consisting of an empty page. The page C# code file
looks like this:

using System;
using System.Web;

namespace StaticMemberTest
{
    public class Test
    {
        static int A
        {
            get { _Default.a++; return _Default.a; }
        }
    }

    public partial class _Default : System.Web.UI.Page
    {
        internal static int a = 0;

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write("A = " + a.ToString());
        }
    }
}

Steps to reproduce the problem:

1. Set the breakpoint within Page_Load
2. Start the debugger.
3. Once the breakpoint is reached, go to Watch window and type "Test.A".
4. This will trigger evaluation of Test.A getter which will increment the
value of _Default.a static variable.
5. Continue the execution, and you will see "A = 1" on the page.
6. Close the browser. Start the page now not in debug mode. It will still
display "A = 1".
7. Try to restart IIS and run the page without debugger. Still "A = 1".
8. If you try to run it in a debugger and evaluate Test.A, it will display
"A = 2". Etc.

The only way to reset the value of a static variable _Default.a is to change
the page source code, so Visual Studio will detect the change and rebuild
the page. Then _Default.a will be reset to 0.

Vagif
Author
23 May 2006 11:23 AM
Göran_Andersson
Vagif Abilov wrote:
> The only way to reset the value of a static variable _Default.a is to change
> the page source code, so Visual Studio will detect the change and rebuild
> the page. Then _Default.a will be reset to 0.

Yes, that is consistent with what i quoted about static variables. The
variable is initialized when the class is loaded the first time.

If you use static variables in a web project, all threads (requests)
will share the same single static variable. Therefore static variables
aren't very useful in a web project.

If you want a static variable to be unique to the thread, you have to
make it [ThreadStatic]. Note though that threadstatic variables only are
initialized for the very first thread that uses the class. For every
thread after that, the value is undefined, so you always have to
initialize a threadstatic variable.
Author
23 May 2006 1:53 PM
Vagif Abilov
Thanks, Gøran! I was not aware of ThreadStatic attribute.

Show quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:Om3MZtlfGHA.4864@TK2MSFTNGP05.phx.gbl...
> Vagif Abilov wrote:
>> The only way to reset the value of a static variable _Default.a is to
>> change the page source code, so Visual Studio will detect the change and
>> rebuild the page. Then _Default.a will be reset to 0.
>
> Yes, that is consistent with what i quoted about static variables. The
> variable is initialized when the class is loaded the first time.
>
> If you use static variables in a web project, all threads (requests) will
> share the same single static variable. Therefore static variables aren't
> very useful in a web project.
>
> If you want a static variable to be unique to the thread, you have to make
> it [ThreadStatic]. Note though that threadstatic variables only are
> initialized for the very first thread that uses the class. For every
> thread after that, the value is undefined, so you always have to
> initialize a threadstatic variable.
Author
23 May 2006 3:04 PM
Ricky Lee
Vagif Abilov wrote:
[...]
Show quote
> Steps to reproduce the problem:
>
> 1. Set the breakpoint within Page_Load
> 2. Start the debugger.
> 3. Once the breakpoint is reached, go to Watch window and type "Test.A".
> 4. This will trigger evaluation of Test.A getter which will increment the
> value of _Default.a static variable.
> 5. Continue the execution, and you will see "A = 1" on the page.
> 6. Close the browser. Start the page now not in debug mode. It will still
> display "A = 1".
> 7. Try to restart IIS and run the page without debugger. Still "A = 1".
> 8. If you try to run it in a debugger and evaluate Test.A, it will display
> "A = 2". Etc.
>
> The only way to reset the value of a static variable _Default.a is to change
> the page source code, so Visual Studio will detect the change and rebuild
> the page. Then _Default.a will be reset to 0.
>
> Vagif
>
>
The static variable will still be 'alive' as long as the asp.net worker
process holding the variable is alive.  Restarting the IIS will not
reinitialize the static variable.  Recycling the aspnet_wp process will do.

Cheers,
R. Lee
Author
23 May 2006 10:57 AM
Mehdi
On Tue, 23 May 2006 08:16:45 +0200, Vagif Abilov wrote:

> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with some
> static variables (reference types) that were not set to null. I received the
> following comment on it:
>
> "only in vb.net are un-initialozed variables set to null. in c# you need to
> do it yourself, as the compiler doesn't emit and initalation code you don't
> include. its a bug in your code. its just luck it worked in 1.1"
>
> I must say that if this it true, it means I was completely misunderstanding
> the way .NET initialized reference type instances. I thought they are set to
> null, i.e. the following declarations of a1 and a2 are equal:

For such specific language questions, do not rely on what "one" says or
think. Head on to the C# specifications document:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_5.asp>
Author
23 May 2006 11:21 AM
Vagif Abilov
Thanks! I was looking for such document.

Actually my problem was caused by the way ASP.NET caches static variables. I
posted the explanation another comment to this thread. Looks like lifetime
of a static variable under ASP.NET goes far beyond lifetime of the session.

Vagif

Show quote
"Mehdi" <vio***@REMOVEME.gmail.com> wrote in message
news:4bcq7gpdizxe$.ci4areunp9vy$.dlg@40tude.net...
> On Tue, 23 May 2006 08:16:45 +0200, Vagif Abilov wrote:
>
>> After porting some code from .NET 1.1 to .NET 2.0 I got a problem with
>> some
>> static variables (reference types) that were not set to null. I received
>> the
>> following comment on it:
>>
>> "only in vb.net are un-initialozed variables set to null. in c# you need
>> to
>> do it yourself, as the compiler doesn't emit and initalation code you
>> don't
>> include. its a bug in your code. its just luck it worked in 1.1"
>>
>> I must say that if this it true, it means I was completely
>> misunderstanding
>> the way .NET initialized reference type instances. I thought they are set
>> to
>> null, i.e. the following declarations of a1 and a2 are equal:
>
> For such specific language questions, do not rely on what "one" says or
> think. Head on to the C# specifications document:
> <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_5.asp>

AddThis Social Bookmark Button