mercredi 16 avril 2014

C++ Interview : vtable pour une classe avec une fonction virtuelle pure - Stack Overflow


I was asked this interview question today!! (it was a really awkward telephonic interview..):



What is the difference between the vtable for a class with virtual functions and a class with pure virtual functions?



Now, I know the C++ standard doesn't specify anything about vtables, or even the existence of a v-table ..however theoretically speaking what would the answer be?


I blurted out that the class with a pure virtual function could have a vtable and its vtable entry for the pure virtual function will point to the derived class implementation. Is this assumption correct? I did not get a positive answer from the interviewer.


Will a hypothetical compiler create a vtable for a class with only pure virtual functions? What if the class contains pure virtual functions with definitions? (as shown in : http://www.gotw.ca/gotw/031.htm).




In the case of non-pure virtual functions, each entry in the vtable will refer to the final-overrider or a thunk that adapts the this pointer if needed. In the case of a pure-virtual function, the entry in the vtable usually contains a pointer to a generic function that complains and aborts the program with some sensible message (pure virtual function called within this context or similar error message).



Will a hypothetical compiler create a vtable for a class with only pure virtual functions?



Yes, it will, the difference will be in the contents stored in the table, not in the shape of the table. In a simplistic approach, a NULL pointer for pure virtual functions, non-NULL for virtual functions. Realistically, a pointer to a generic function that will complain and abort() with usual compilers.



What if the class contains pure virtual functions with definitions?



This will not affect the vtable. The vtable is only used for dynamic dispatch, and a call will never be dynamically dispatched to the definition of a pure virtual function (i.e. you can only manually dispatch to the pure virtual function by disabling dynamic dispatch qualifying the name of the type: x.base::f() will call base::f even if it is pure-virtual, but x.f() will never be dispatched to base::f if it is pure virtual.




I can tell you that "pure" abstract classes (classes with only pure virtual functions) are used by Microsoft (and MS VC++) for their COM interfaces. Perhaps he was speaking of it. The "internal" representation of a COM is a pointer to a vtable. Pure abstract classes in MS VC++ are implemented in the same way, so you can use them to represent COM objects. Clearly if you class has other virtual functions, you can't simply overwrite its vtable with the COM vtable :-)




An implementation can do pretty much anything in such cases, because if your code ends up calling a pure virtual function in a context where dynamic resolution is required, and it would resolve to a pure virtual function, the behavior is undefined. I've seen several different solutions: the compiler inserts the address of a function which terminates with an error message (the preferred solution from a quality of implementation point of view), the compiler inserts a null pointer, or the compiler inserts the address of the function from some derived class. I've also seen cases where the compiler will insert the address of the function if you provide an implementation. The only correct answer to the question is that you can't count on any particular behavior.




Please read this article further clarification: http://www.artima.com/cppsource/pure_virtual.html



I was asked this interview question today!! (it was a really awkward telephonic interview..):



What is the difference between the vtable for a class with virtual functions and a class with pure virtual functions?



Now, I know the C++ standard doesn't specify anything about vtables, or even the existence of a v-table ..however theoretically speaking what would the answer be?


I blurted out that the class with a pure virtual function could have a vtable and its vtable entry for the pure virtual function will point to the derived class implementation. Is this assumption correct? I did not get a positive answer from the interviewer.


Will a hypothetical compiler create a vtable for a class with only pure virtual functions? What if the class contains pure virtual functions with definitions? (as shown in : http://www.gotw.ca/gotw/031.htm).



In the case of non-pure virtual functions, each entry in the vtable will refer to the final-overrider or a thunk that adapts the this pointer if needed. In the case of a pure-virtual function, the entry in the vtable usually contains a pointer to a generic function that complains and aborts the program with some sensible message (pure virtual function called within this context or similar error message).



Will a hypothetical compiler create a vtable for a class with only pure virtual functions?



Yes, it will, the difference will be in the contents stored in the table, not in the shape of the table. In a simplistic approach, a NULL pointer for pure virtual functions, non-NULL for virtual functions. Realistically, a pointer to a generic function that will complain and abort() with usual compilers.



What if the class contains pure virtual functions with definitions?



This will not affect the vtable. The vtable is only used for dynamic dispatch, and a call will never be dynamically dispatched to the definition of a pure virtual function (i.e. you can only manually dispatch to the pure virtual function by disabling dynamic dispatch qualifying the name of the type: x.base::f() will call base::f even if it is pure-virtual, but x.f() will never be dispatched to base::f if it is pure virtual.



I can tell you that "pure" abstract classes (classes with only pure virtual functions) are used by Microsoft (and MS VC++) for their COM interfaces. Perhaps he was speaking of it. The "internal" representation of a COM is a pointer to a vtable. Pure abstract classes in MS VC++ are implemented in the same way, so you can use them to represent COM objects. Clearly if you class has other virtual functions, you can't simply overwrite its vtable with the COM vtable :-)



An implementation can do pretty much anything in such cases, because if your code ends up calling a pure virtual function in a context where dynamic resolution is required, and it would resolve to a pure virtual function, the behavior is undefined. I've seen several different solutions: the compiler inserts the address of a function which terminates with an error message (the preferred solution from a quality of implementation point of view), the compiler inserts a null pointer, or the compiler inserts the address of the function from some derived class. I've also seen cases where the compiler will insert the address of the function if you provide an implementation. The only correct answer to the question is that you can't count on any particular behavior.



Please read this article further clarification: http://www.artima.com/cppsource/pure_virtual.html


0 commentaires:

Enregistrer un commentaire