"new" on value types

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Jamie Julius (jamie_at_netvision.net.il)
Date: 02/21/05


Date: Mon, 21 Feb 2005 09:16:28 +0200

Consider the following struct:

struct TestStruct
{
    public int a, b, c;

    public TestStruct(int a, int b, int c)
    {
        this.a = a;

        if (b == 6)
        {
            throw new ArgumentException("I don't like 6", "b");
        }

        this.b = b;
        this.c = c;
    }
}

The C# spec says in section 7.5.10.1:

The run-time processing of an object-creation-expression of the form new
T(A) ... If T is a struct-type:
An instance of type T is created by allocating a temporary local variable.

>From this I would assume that if I write the following:

TestStruct ts = new TestStruct();

ts = new TestStruct(1, 2, 3);
ts = new TestStruct(3, 6, 9);

The compiler should invoke the constructor on temporary instances and
subsequently copy the temporaries into "ts". This would imply that if the
constructor throws an exception, "ts" will remain with its original value.

However, the C# compiler seems to pass "ts" itself into the constructor as
the "this" instance (i.e., not a temporary):

IL_0008: ldloca.s ts
IL_000a: ldc.i4.1
IL_000b: ldc.i4.2
IL_000c: ldc.i4.3
IL_000d: call instance void Testing.Item03/TestStruct::.ctor(int32, int32,
int32)

Indeed, if the constructor throws an exception after changing some of the
fields, "ts" results in an inconsistent state.

Basically, I'm curious as to anyone's opinion as to whether this is a
compiler bug, or is the assignment of the value produced by the 'new'
operator a special case.

For comparison, if I change the above to the following:

ts = newTestStruct(1, 2, 3);

where the following is defined:

static TestStruct newTestStruct(int a, int b, int c)
{
    return new TestStruct(a, b, c);
}

I get the consistent behavior I was hoping for.

Thanks,

Jamie



Relevant Pages

  • Very weird compiler bug or normal ISO C++ behaviour?
    ... I went across what seems possibly a bug of the compiler (VisualC 2005, ... the wrong constructor will be called.. ... struct Two: One { ...
    (microsoft.public.vc.language)
  • Re: Questions
    ... Would you want that to call the parameterless constructor 100 times? ... struct Derived: Base ... either disallow this, or only *actually* use a Base even though you've ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: new X vs new X()
    ... >> constructor, then the default constructor for T ... int array[1000]; ... out of 4 of my compilers returned true, true, 1 returned false, true. ...
    (comp.lang.cpp)
  • Re: why the leaking? please advise
    ... you declared a pointer to a map that maps strings to B ... > struct B; ... > int a; ... > Is my B's copy constructor correct? ...
    (microsoft.public.vc.language)
  • Re: Obscure marshalling/pinvoke problem with 1, 2, 4, and 8 bytes structures
    ... struct TestStruct ... public struct TestStruct ... public float f; ... public static TestStruct GetTest() {return TestPINVOKE.<exported ...
    (microsoft.public.dotnet.framework.interop)