Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8206259
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T08:36:31+00:00 2026-06-07T08:36:31+00:00

This is from the C++11 standard sec 12.7.4. This is rather confusing. What does

  • 0

This is from the C++11 standard sec 12.7.4. This is rather confusing.

  1. What does the last sentence in the text mean exactly?
  2. Why is the last method call in B::B undefined? Shoudn’t it just call a.A::f?

4 Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2). When a virtual function
is called directly or indirectly from a constructor or from a
destructor, including during the construction or destruction of the
class’s non-static data members, and the object to which the call
applies is the object (call it x) under construction or destruction,
the function called is the final overrider in the constructor’s or
destructor’s class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access
(5.2.5) and the object expression refers to the complete object of x
or one of that object’s base class subobjects but not x or one of its
base class subobjects, the behavior is undefined. [ Example:

struct V {
 virtual void f();
 virtual void g();
};

struct A : virtual V {
 virtual void f();
};

struct B : virtual V {
 virtual void g();
 B(V*, A*);
};

struct D : A, B {
 virtual void f();
 virtual void g();
 D() : B((A*)this, this) { }
};

B::B(V* v, A* a) {
 f(); // calls V::f, not A::f
 g(); // calls B::g, not D::g
 v->g(); // v is base of B, the call is well-defined, calls B::g
 a->f(); // undefined behavior, a’s type not a base of B
}

—end example ]

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T08:36:34+00:00Added an answer on June 7, 2026 at 8:36 am

    That portion of the standard is simply telling you that when you are constructing some “large” object J whose base class hierarchy includes multiple inheritance, and you are currently sitting inside the constructor of some base subobject H, then you are only allowed to use polymorphism of H and its direct and indirect base subobjects. You are not allowed to use any polymorphism outside that subhierarchy.

    For example, consider this inheritance diagram (arrows point from derived classes to base classes)

    enter image description here

    Let’s say we are constructing a “large” object of type J. And we are currently executing the constructor of class H. Inside the constructor of H you are allowed to enjoy typical constructor-restricted polymorphism of the subhierarchy inside the red oval. For example, you can call virtual functions of base subobject of type B, and the polymorphic behavior will work as expected inside the circled subhierarchy (“as expected” means that the polymorphic behavior will go as low as H in the hierarchy, but no lower). You can also call virtual functions of A, E, X and other subobjects that fall inside the red oval.

    However, if you somehow gain access to the hierarchy outside the oval and attempt to use polymorphism there, the behavior becomes undefined. For example, if you somehow gain access to G subobject from the constructor of H and attempt to call a virtual function of G – the behavior is undefined. The same can be said about calling virtual functions of D and I from the constructor of H.

    The only way to obtain such access to the “outside” subhierarchy is if someone somehow passed a pointer/reference to G subobject into the constructor of H. Hence the reference to “explicit class member access” in the standard text (although it seems to be excessive).

    The standard includes virtual inheritance into the example to demonstrate how inclusive this rule is. In the above diagram base subobject X is shared by both the subhierarchy inside the oval and subhierarchy outside the oval. The standard says that it is OK to call virtual functions of X subobject from the constructor of H.

    Note that this restriction applies even if the construction of D, G and I subobjects has been finished before the construction of H began.


    The roots of this specification lead to practical consideration of implementing polymorphic mechanism. In practical implementations the VMT pointer is introduced as a data field into the object layout of the most basic polymorphic classes in the hierarchy. Derived classes don’t introduce their own VMT pointers, they simply provide their own specific values for the pointers introduced by the base classes (and, possibly, longer VMTs).

    Take a look at the example from the standard. The class A is derived from class V. This means that the VMT pointer of A physically belongs to V subobject. All calls to virtual functions introduced by V are dispatched through VMT pointer introduced by V. I.e. whenever you call

    pointer_to_A->f();
    

    it is actually translated into

    V *v_subobject = (V *) pointer_to_A; // go to V
    vmt = v_subobject->vmt_ptr;          // retrieve the table
    vmt[index_for_f]();                  // call through the table
    

    However, in the example from the standard the very same V subobject is also embedded into B. In order to make the constructor-restricted polymorphism work correctly, the compiler will place a pointer to B‘s VMT into VMT pointer stored in V (because while B‘s constructor is active V subobject has to act as part of B).

    If at this moment you somehow attempt to call

    a->f(); // as in the example
    

    the above algorithm will find B‘s VMT pointer stored in its V subobject and will attempt to call f() through that VMT. This obviously makes no sense at all. I.e. having virtual methods of A dispatched through B‘s VMT makes no sense. The behavior is undefined.

    This is rather simple to verify with practical experiment. Let’s add its own version of f to B and do this

    #include <iostream>
    
    struct V {
      virtual void f() { std::cout << "V" << std::endl; }
    };
    
    struct A : virtual V {
      virtual void f() { std::cout << "A" << std::endl; }
    };
    
    struct B : virtual V {
      virtual void f() { std::cout << "B" << std::endl; }
      B(V*, A*);
    };
    
    struct D : A, B {
      virtual void f() {}
      D() : B((A*)this, this) { }
    };
    
    B::B(V* v, A* a) {
      a->f(); // What `f()` is called here???
    }
    
    int main() {
      D d;
    }
    

    You expect A::f to be called here? I tried several compilers, an all of them actually call B::f! Meanwhile, the this pointer value B::f receives in such call is completely bogus.

    http://ideone.com/Ua332

    This happens exactly for the reasons I described above (most compilers implement polymorphism the way I described above). This is the reason the language describes such calls as undefined.

    One might note that in this specific example it is actually the virtual inheritance that leads to this unusual behavior. Yes, it happens exactly because the V subobject is shared between A and B subobjects. It is quite possible that without virtual inheritance the behavior would be much more predictable. However, the language specification apparently decided to just draw line the the way it is drawn in my diagram: when you are constructing H you are not allowed to step out of the “sandbox” of H‘s subhierarchy regardless of what inheritance type is used.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Jakob Østergaard presented this challenge: Write a program that reads text from standard-input, and
Consider this is a standard Linq from q in SomeQuery select new SomeObject {
Is this from the C standard?
This is a sample input form from wordpress standard coding (I get it from
This is the statement from ISO C++ Standard 14.6.4.1 Point of instantiation For a
This is the statement from ISO C++ Standard 14.6.4.1 Point of instantiation 4.If a
I have query like this: SELECT *, SUM(ss.rank) as group_sum FROM Standard s, s.SubStandard
This is a follow-up question on Delete field from standard Django model . In
I'm talking about this surprisingly simple implementation of rand() from the C standard: static
From LinkedIn API I got this hash: > #<LinkedIn::Mash all=[#<LinkedIn::Mash api_standard_profile_request=#<LinkedIn::Mash headers=#<LinkedIn::Mash > all=[#<LinkedIn::Mash

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.