[nem-bug] [Nemerle 0000644]: Wrong behavior during base ctor call
feedback at nemerle.org
feedback at nemerle.org
Mon Apr 3 23:41:09 CEST 2006
A NOTE has been added to this issue.
======================================================================
<http://nemerle.org/bugs/view.php?id=644>
======================================================================
Reported By: VladD2
Assigned To:
======================================================================
Project: Nemerle
Issue ID: 644
Category: Compiler
Reproducibility: always
Severity: minor
Priority: normal
Status: new
======================================================================
Date Submitted: 04-02-2006 21:53 CEST
Last Modified: 04-03-2006 23:41 CEST
======================================================================
Summary: Wrong behavior during base ctor call
Description:
This code:
using System.Console;
class A
{
public this() { WriteLine("A()"); }
}
class B : A
{
public this()
{
WriteLine("B()");
base();
}
}
def b = B();
print:
A()
B()
A()
i.e. occur unnecessary ctor call.
In the more complex case:
class A
{
public this(_ : int) { WriteLine("A()"); }
}
class B : A
{
public this(_ : int)
{
WriteLine("B()");
base(2);
}
}
def b = B(1);
ncc generate error:
test-016.n:12:3:15:4: error: wrong number of parameters in call, needed 1,
got 0
test-016.n:12:3:15:4: error: typing error in call
======================================================================
----------------------------------------------------------------------
nazgul - 04-02-06 23:21
----------------------------------------------------------------------
I guess there is some restriction in IL where base call should occur. In C#
there is even a special syntax, which will not allow to execute arbitrary
code before base call.
Compiler should probably report an error about usage of base not on the
beginning of constructor, but it is not clear for me why for example
base(x + 3 + f()) is allowed, but a sequence of statements isn't.
----------------------------------------------------------------------
VladD2 - 04-03-06 15:05
----------------------------------------------------------------------
I've created a C#-sample, where were 2 classes, one of them inherited from
another. Constructors of those classes print to console the information
about constructor calls. Then I decompiled the resulting assembly into IL
(by ILDASM), commented out the call of base class constructor and compiled
with ILASM. The compilation was successful, and execution of the result
assembly printed out only the information about the call of the inherited
class.
So, there are no "physical" problems in IL, preventing the realization of
correct behaviour.
It's rather serious problem, and I think it needs an urgent correction.
----------------------------------------------------------------------
nazgul - 04-03-06 15:11
----------------------------------------------------------------------
Did you run verifier on the resulting assebly (PEVerify.exe from SDK)
----------------------------------------------------------------------
VladD2 - 04-03-06 18:46
----------------------------------------------------------------------
Hm... Really, if I'd not call the base ctor, PEVerify.exe reports an
error.
Nevertheless, if the commented ctor call is moved forward, to the end of
inherited class ctor, everything works fine, and PEVerify doesn't report
any error.
----------------------------------------------------------------------
VladD2 - 04-03-06 18:49
----------------------------------------------------------------------
This code:
<<
.class private auto ansi beforefieldinit A
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldstr "A()"
IL_000d: call void [mscorlib]System.Console::WriteLine(string)
IL_0012: nop
IL_0013: nop
IL_0014: ret
} // end of method A::.ctor
} // end of class A
.class private auto ansi beforefieldinit B
extends A
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0006: nop
IL_0007: nop
IL_0008: ldstr "B()"
IL_000d: call void [mscorlib]System.Console::WriteLine(string)
IL_0000: ldarg.0
IL_0001: call instance void A::.ctor()
IL_0012: nop
IL_0013: nop
IL_0014: ret
} // end of method B::.ctor
} // end of class B
.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 8 (0x8)
.maxstack 1
.locals init ([0] class B b)
IL_0000: nop
IL_0001: newobj instance void B::.ctor()
IL_0006: stloc.0
IL_0007: ret
} // end of method Program::Main
>>
compiled and trint:
B()
A()
and >PEVerify.exe rport:
All Classes and Methods in a.exe Verified.
----------------------------------------------------------------------
nazgul - 04-03-06 18:50
----------------------------------------------------------------------
I see, this is quite interesting information. It would be nice to allow
base ctor calls in the middle of code, I miss this feature from time to
time.
The hard part is that a few places needs to be changed in compiler and
we'd need the proper handling of error situations (like calling base ctor
twice, which should be rejected)
----------------------------------------------------------------------
VladD2 - 04-03-06 19:03
----------------------------------------------------------------------
In fact you already declade this behaviour in tutorials, and IMHI this
feature really cool.
Now behaviour of base ctor call just incorrect, and you must something do
to correc this situation.
----------------------------------------------------------------------
VladD2 - 04-03-06 19:17
----------------------------------------------------------------------
> like calling base ctor twice, which should be rejected
At first it's OK without ctor double call control. In future is necessary
to implemend flow control which allow to solve many problems (not only
this).
----------------------------------------------------------------------
malekith - 04-03-06 23:16
----------------------------------------------------------------------
The real problem here is that one cannot use the this pointer prior to
calling base constructor. And I believe this will be hard to check,
especially if 'this' gets into the closure.
----------------------------------------------------------------------
nazgul - 04-03-06 23:18
----------------------------------------------------------------------
I tried using 'this' before call and it verifies - at least assigning to
the fields. Maybe other uses are forbidden.
----------------------------------------------------------------------
nazgul - 04-03-06 23:21
----------------------------------------------------------------------
This also verifies:
public D () {
System.Console.WriteLine (x);
x = 6;
y = 55;
base (1) // moved in IL to here
}
(x is defined in superclass, and y in D)
----------------------------------------------------------------------
VladD2 - 04-03-06 23:41
----------------------------------------------------------------------
> The real problem here is that one cannot use the this pointer prior to
calling base constructor. And I believe this will be hard to check,
especially if 'this' gets into the closure.
IMHO it's not problem. CLR allow it.
In C# it is possible to call overridden metods in ctor and it behaviour
don't confuse anybody. After all in CLR all member field initialise to
0/null.
CLR != C++. :)
Issue History
Date Modified Username Field Change
======================================================================
04-02-06 21:53 VladD2 New Issue
04-02-06 23:21 nazgul Note Added: 0001139
04-03-06 15:05 VladD2 Note Added: 0001141
04-03-06 15:11 nazgul Note Added: 0001143
04-03-06 18:46 VladD2 Note Added: 0001145
04-03-06 18:49 VladD2 Note Added: 0001146
04-03-06 18:50 nazgul Note Added: 0001147
04-03-06 19:03 VladD2 Note Added: 0001149
04-03-06 19:17 VladD2 Note Added: 0001150
04-03-06 23:16 malekith Note Added: 0001153
04-03-06 23:18 nazgul Note Added: 0001154
04-03-06 23:21 nazgul Note Added: 0001155
04-03-06 23:41 VladD2 Note Added: 0001158
======================================================================
More information about the bugs
mailing list