Firstly, this code is not compilable, since in C++ void *
cannot be implicitly converted to A *
. An explicit cast is required.
Secondly, the example with malloc
is completely irrelevant. malloc
allocates raw memory, with has absolutely no relation to any specific types. In this case malloc
knows noting about any A
and it does not create an object of type A
.
For this reasons the real example for this question should look as follows
struct A
{
virtual void foo(); // unused and unimplemented
virtual void bar () {}
};
int main ()
{
A obj; // ok
A* pn = new A; // linker error
}
And the question is why the first declaration produces no liker error while the second one does.
From the formal point of view, your program is invalid because it violates formal requirements of C++ language (specifically ODR). In practice, both declarations could or should produce the same error, since in both cases the object formally requires a pointer to VMT. In this case VMT cannot be created, since some functions are undefined. However, the first declaration simply slips through just because the compiler was able to optimize-out all references to VMT for the first declaration (and not for the second). It is also quite possible that the compiler was able to optimize-out the whole obj
object, since it is not referenced anywhere else.
In GCC (since you appear to be using GCC) it is easy to trigger the same error for the first declaration as well
struct A
{
virtual void foo(); // unused and unimplemented
virtual void bar () {}
};
int main ()
{
A obj; // linker error
A *p = &obj;
p->bar();
}
The above code will produce the same linker error in GCC even though the undefined function foo
is still not used in this code.
In other words, it is simply a matter of adding sufficient amount of code to make the compiler believe that the object's VMT is needed. The difference in behavior between the declarations has nothing to do with C++ language in this case. It is just an implementation issue specific to your compiler.
malloc
. – RejoinA obj;
ideone.com/AYYle – Tatianiamalloc()
how can it be a fake code just for that ? I have edited it though. – Tatiania