The interface's 'in' contract passes if it makes a virtual function call
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Nov 4 12:26:58 PST 2014
On 11/4/14 3:01 PM, Ali Çehreli wrote:
> Perhaps I am expecting too much from the current 'in' contract design
> and implementation. ;)
>
> Still, the virtual function call in the following interface's 'in'
> contract should be dispatched to the implementaion in the derived class,
> right?
>
> It seems like mere presence of that virtual function call causes the
> 'in' contract of the interface succeed and the derived's 'in' contract
> never gets called.
>
> import std.stdio;
>
> void main()
> {
> /* EXPECTATION: The following call should execute both the
> * base's and the derived's in contracts 50% of the time
> * because the base's contract fails randomly. */
> (new C()).foo();
> }
>
> interface I
> {
> void foo()
> in {
> writeln("I.foo.in");
>
> /* This check succeeds without calling virtualCheck! */
> assert(virtualCheck());
> }
>
> bool virtualCheck();
> }
>
> class C : I
> {
> void foo()
> in {
> writeln("C.foo.in");
> }
> body
> {}
>
> bool virtualCheck()
> {
> writeln("C.virtualCheck");
>
> /* Fail randomly 50% of the time */
> import std.random;
> import std.conv;
> return uniform(0, 2).to!bool;
> }
> }
>
> The output has no mention of C.virtualCheck nor C.foo.in:
>
> I.foo.in
> <-- Where is C.virtualCheck?
> <-- Where is C.foo.in?
>
> Ali
This looks like a dmd bug. My theory is that the call to virtualCheck is
going to the WRONG vtbl address. I have seen stuff like this before. It
likely is calling something like toString. You would have to debug to
figure it out.
So what I think happens is it calls the wrong virtual function, which
returns non-zero always, and obviously doesn't print anything, and then
continues on. I added a writeln("after virtual check") to the in
contract of I.foo, and it writes that too.
-Steve
More information about the Digitalmars-d-learn
mailing list