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 9147935
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T11:07:30+00:00 2026-06-17T11:07:30+00:00

I’m puzzled with this behavior of C++: struct A { virtual void print() const

  • 0

I’m puzzled with this behavior of C++:

struct A {
   virtual void print() const { printf("a\n"); }
};

struct B : public A {
   virtual void print() const { printf("b\n"); }
};

struct C {
   operator B() { return B(); }
};

void print(const A& a) {
   a.print();
}

int main() {
   C c;
   print(c);
}

So, the quiz is, what is the output of the program – a or b? Well, the answer is a. But why?

  • 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-17T11:07:32+00:00Added an answer on June 17, 2026 at 11:07 am

    The problem here is a bug / misfeature / hole in the C++03 standard, with different compilers trying to patch over the problem in different ways. (This problem no longer exists in C++11 standard.)

    Sections 8.5.3/5 of both standards specify how a reference is initialized. Here’s the C++03 version (the list numbering is mine):

    A reference to type cv1 T1 is initialized by an expression of type cv2 T2 as follows:

    1. If the initializer expression

      1. is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or
      2. has a class type (i.e., T2 is a class type) and can be implicitly converted to an lvalue of type cv3 T3, where cv1 T1 is reference-compatible with cv3 T3

      then the reference is bound directly to the initializer expression lvalue in the first case, and the reference is bound to the lvalue result of the conversion in the second case.

    2. Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const).

    3. If the initializer expression is an rvalue, with T2 a class type, and cv1 T1 is reference-compatible with cv2 T2, the reference is bound in one of the following ways (the choice is implementation-defined):

      1. The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
      2. A temporary of type cv1 T2 [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.

      The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.

    4. Otherwise, a temporary of type cv1 T1 is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary.

    There are three types involved in the question at hand:

    • The type of the reference to be created. The standards (both versions) denote this type as T1. In this case, it is struct A.
    • The type of the initializer expression. The standards denote this type as T2. In this case, the initializer expression is the variable c, so T2 is struct C. Note that because struct A is not reference-compatible with struct C, it’s not possible to directly bind the reference to c. An intermediate is needed.
    • The type of the intermediate. The standards denote this type as T3. In this case, this is struct B. Note that applying the conversion operator C::operator B() to c will convert the lvalue c to an rvalue.

    The initializations by what I labeled as 1.1 and 3 are out because the struct A is not reference-compatible with struct C. The conversion operator C::operator B() needs to be used. 1.2 is out Because this conversion operator returns an rvalue, this rules 1.2 out. All that is left is option 4, create a temporary of type cv1 T1. Strict compliance with the 2003 version of the standard forces the creation of two temporaries for this problem, even though only one will suffice.

    The 2011 version of the standard fixes the problem by replacing option 3 with

    • If the initializer expression

      • is an xvalue, class prvalue, array prvalue or function lvalue and cv1 T1 is reference-
        compatible with cv2 T2, or
      • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an xvalue, class prvalue, or function lvalue of type cv3 T3, where cv1 T1 is reference-compatible with cv3 T3,

      then the reference is bound to the value of the initializer expression in the first case and to the result of the conversion in the second case (or, in either case, to an appropriate base class subobject). In the second case, if the reference is an rvalue reference and the second standard con- version sequence of the user-defined conversion sequence includes an lvalue-to-rvalue conversion, the program is ill-formed.

    It appears that the gcc family of compilers chose strict compliance over intent (avoid creating unnecessary temporaries), while the other compilers that print “b” chose intent / corrections to the standard. Choosing strict compliance isn’t necessarily commendable; there are other bugs/misfeatures in the 2003 version of the standard (e.g., std::set) where the gcc family chose sanity over strict compliance.

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

Sidebar

Related Questions

I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
Let's say I'm outputting a post title and in our database, it's Hello Y’all
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I have this code to decode numeric html entities to the UTF8 equivalent character.
This could be a duplicate question, but I have no idea what search terms

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.