3

according to this virtual functions must be defined otherwise linker complains & reports error "undefined reference to vtable", but why doesn't ideone compiler give any errors for the following code?

#include <iostream>
using namespace std;
class Test
{
    public:
    Test()
    {
        cout<<"test() is called\n";
    }
    virtual void test();
};
int main() {
    Test t;
    // your code goes here
    return 0;
}
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
Destructor
  • 14,123
  • 11
  • 61
  • 126
  • 4
    You aren't calling the undefined member anywhere. – juanchopanza Feb 23 '15 at 13:39
  • 1
    @juanchopanza I have seen on some compilers that undefined virtual functions results in errors even if the member is not called. I can't remember if that's allowed by the standard or not. – Neil Kirk Feb 23 '15 at 13:40
  • Related, refers to C++03 http://stackoverflow.com/questions/8642124/should-a-virtual-function-essentially-have-a-definition – Neil Kirk Feb 23 '15 at 13:42
  • 1
    Probably because (after inlining and other optimisations) the program never tries to use the *vtable*, so there aren't any references that need defining. You'd probably still get an error if you did anything that needed it. – Mike Seymour Feb 23 '15 at 13:44
  • @NeilKirk That's plausible. But I am pretty sure calling `Test::test()` would have triggered an error. – juanchopanza Feb 23 '15 at 13:44
  • @juanchopanza: Not necessarily. In a simple example like this, the dynamic type is known at compile time, so it's likely to be called non-virtually. – Mike Seymour Feb 23 '15 at 13:46
  • 1
    @MikeSeymour: And, when it is, the call will fail because no definition is available. – Lightness Races in Orbit Feb 23 '15 at 13:46
  • @LightnessRacesinOrbit: Sorry, I wasn't thinking straight. Of course you'll get an error; but perhaps not the one about a missing vtable (which is what the question is about). – Mike Seymour Feb 23 '15 at 13:48
  • C++ is case-sensitive, so the constructor `Test::Test()` is different from the virtual function `void Test::test()`. And it only produces an error (in the linking step) when an undefined function is called. – tmlen Feb 24 '15 at 10:28
  • @tmlen: Not necessarily. It can also produce the error the question is asking about if a virtual function is undefined, even if no virtual function is called. A less trivial example, which can't optimise out the object creation, would need to initialise the object's *vtable*, and would fail if that didn't exist. This particular compiler produces the *vtable* in the same translation unit as the first non-pure, non-virtual function (if there is such a thing), and will fail to produce it if that function isn't defined. – Mike Seymour Feb 24 '15 at 11:37

1 Answers1

7

You didn't read the documentation properly. The first sentence in the relevant paragraph says:

The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined, but does not require any diagnostic for violations of this rule [class.virtual]/8.

So, it is expected that you may not get an error, especially since you are not actually invoking test() (despite the lie in the constructor's output).

Speaking practically, you are likely to get this diagnostic only under the following circumstances:

  • you call a virtual function that you did not define
  • you instantiate an object whose virtual destructor you did not define

But make no mistake: your program has undefined behaviour regardless.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055