views:

218

answers:

2

This is probably habitual programming redundancy. I have noticed DECLSPEC_NOVTABLE ( __declspec(novtable) ) on a bunch of interfaces defined in headers:

struct DECLSPEC_NOVTABLE IStuff : public IObject
{
    virtual method1 () = 0;
    virtual method2 () = 0;
};

The MSDN article on this __declspec extended attribute says that adding this guy will remove the construct and desctructor vtable entries and thus result in "significant code size reduction" (because the vtable will be removed entirely).

This just doesn't make much sense to me. These guys are pure virtual, why wouldn't the compiler just do this by default?

The article also says that if you do this, and then try and instantiate one of these things, you will get a run time access violation. But when I tried this with a few compilers (with or without the __declspec extension), they don't compile (as I would have expected).

So I guess to summarize:

  • Does the compiler strip out the vtable regardless for pure virtual interfaces, or have I missed something fundamental here?
  • What is the MSDN article talking about ?
+2  A: 

The compiler strips out the only reference to the vtable, which would have been during construction of the class. Therefore, the linker can optimize it away since there is no longer a reference in the code to it.

Also by the way, I have made a habit of declaring an empty constructor as protected, and also using Microsoft's extension abstract keyword, to avoid that access violation at runtime. This way, the compiler catches the problem at compile time instead (since only a base class can instantiate the interface through the protected constructor). The derived class will of course fill in the vtable during its construction.

zildjohn01
Why do you wan't avoid the runtime access violation? Isn't good to know when someone is instantiating a pure virtual class? Still a bit fuzzy on this ;).
Cannonade
It catches the error at compile time instead. Answer edited.
zildjohn01
+1  A: 

It's a bit of handholding for a dumb compiler/linker. The compiler should not insert any reference to this vtable, as it is quite obvious that there is no need for this vtable. The compiler could also mark the reference in such a way that the linker can eliminate the vtable, but that's more complex of course.

MSalters