virtual methods, virtual bases bug<?> in G++ 3.3

Discussion in 'C++' started by Jim Fischer, Jul 30, 2003.

  1. Jim Fischer

    Jim Fischer Guest

    Paragraph 10.3/2 in the C++ standard [ISO/IEC 14882:1998] has the
    following code example:

    <quote>
    struct A {
    virtual void f();
    };
    struct B : virtual A {
    virtual void f();
    };

    struct C : B , virtual A {
    using A::f;
    };
    void foo() {
    C c;
    c.f(); // calls B::f, the final overrider
    c.C::f(); // calls A::f because of the usingdeclaration
    }
    </quote>

    It seems a little odd (to me) that the method call 'c.f()' in function
    foo() should invoke B::f. I thought it would invoke A::f due to the
    using declaration 'using A::f;' in class C's declaration block. And in
    fact, when I use G++ 3.3 to build the code sample shown below, the
    method call 'c.f()' invokes A::f (which is what I expected), and not
    B::f as stated in the C++ standard.

    <example>

    <code main.cpp>
    #include <iostream>

    struct A {
    virtual void f() { std::cout << "A::f()\n"; }
    };
    struct B : virtual A {
    virtual void f() { std::cout << "B::f()\n"; }
    };
    struct C : B, virtual A {
    using A::f;
    };

    int main()
    {
    C c;
    c.f(); // g++ 3.3 invokes A::f, not B::f
    c.C::f();
    }
    </code main.cpp>

    <build>
    g++ main.cpp
    </build>

    <output>
    A::f()
    A::f()
    </output>

    </example>

    FWIW, I looked around on the "JTC1/SC22/WG21 - C++" web site,

    http://anubis.dkuug.dk/jtc1/sc22/wg21/

    but I didn't find anything about this particular issue (e.g., in the
    "Core Language Issues" pages). So I'd like some verification that c.f()
    is indeed supposed to invoke B::f, as stated in the standard, and not A::f.

    --
    Jim

    To reply by email, remove "link" and change "now.here" to "yahoo"
    jfischer_link5809{at}now.here.com
    Jim Fischer, Jul 30, 2003
    #1
    1. Advertising

  2. Jim Fischer wrote:

    > void foo() {
    > C c;
    > c.f(); // calls B::f, the final overrider
    > c.C::f(); // calls A::f because of the usingdeclaration
    > }
    > </quote>
    >
    > It seems a little odd (to me) that the method call 'c.f()' in function
    > foo() should invoke B::f. I thought it would invoke A::f due to the
    > using declaration 'using A::f;' in class C's declaration block. And in
    > fact, when I use G++ 3.3 to build the code sample shown below, the
    > method call 'c.f()' invokes A::f (which is what I expected), and not
    > B::f as stated in the C++ standard.
    >


    I think there is some rational explanation.

    If the member function name is not (scope) qualified (like c.f()) then
    the final overrider is called.

    If it is, the name used in the qualified scope is chosen. As shows the
    example member function name does not have to be overridden, it may be
    referred by using directive. But in this case such a name is not
    considered when looking for overriders so the last overrider down in the
    hierarchy is chosen.

    Btw, Borland C++ compiles the example according to the standard.

    Regards,
    Janusz
    Janusz Szpilewski, Jul 31, 2003
    #2
    1. Advertising

  3. "Jim Fischer" <> wrote...
    > Paragraph 10.3/2 in the C++ standard [ISO/IEC 14882:1998] has the
    > following code example:
    >
    > <quote>
    > struct A {
    > virtual void f();
    > };
    > struct B : virtual A {
    > virtual void f();
    > };
    >
    > struct C : B , virtual A {
    > using A::f;
    > };
    > void foo() {
    > C c;
    > c.f(); // calls B::f, the final overrider
    > c.C::f(); // calls A::f because of the usingdeclaration
    > }
    > </quote>
    >
    > It seems a little odd (to me) that the method call 'c.f()' in function
    > foo() should invoke B::f. I thought it would invoke A::f due to the
    > using declaration 'using A::f;' in class C's declaration block. And in
    > fact, when I use G++ 3.3 to build the code sample shown below, the
    > method call 'c.f()' invokes A::f (which is what I expected), and not
    > B::f as stated in the C++ standard.


    Did you actually read the paragraph preceding the example? Name
    lookup for the call

    c.f();

    ignores names introduced by using declarations. That is, C::f is
    ignored, and B::f is found.

    So, G++ v3.3 is buggy. Name resolution is a tricky thing, not all
    of the implementations do it right.

    Victor
    Victor Bazarov, Jul 31, 2003
    #3
  4. Jim Fischer

    Jim Fischer Guest

    Janusz Szpilewski wrote:
    > Jim Fischer wrote:
    >
    >> void foo() {
    >> C c;
    >> c.f(); // calls B::f, the final overrider
    >> c.C::f(); // calls A::f because of the usingdeclaration
    >> }
    >> </quote>
    >>
    >> It seems a little odd (to me) that the method call 'c.f()' in function
    >> foo() should invoke B::f. I thought it would invoke A::f due to the
    >> using declaration 'using A::f;' in class C's declaration block. And in
    >> fact, when I use G++ 3.3 to build the code sample shown below, the
    >> method call 'c.f()' invokes A::f (which is what I expected), and not
    >> B::f as stated in the C++ standard.
    >>

    >
    > I think there is some rational explanation.
    >
    > If the member function name is not (scope) qualified (like c.f()) then
    > the final overrider is called.
    >
    > If it is, the name used in the qualified scope is chosen. As shows the
    > example member function name does not have to be overridden, it may be
    > referred by using directive. But in this case such a name is not
    > considered when looking for overriders so the last overrider down in the
    > hierarchy is chosen.
    >
    > Btw, Borland C++ compiles the example according to the standard.


    Thanks for the reply. I understand the meaning of paragraph 10.3/2
    (although the description given in the standard is different from what I
    originally expected, but of course that's irrelevant). I was basically
    looking for confirmation that 10.3/2 still applies -- that there have
    not been any official changes to that particular paragraph -- before
    submitting a bug report to the GNU g++ maintainers. FWIW, this afternoon
    I submitted a G++ bugzilla report on this issue.

    --
    Jim

    To reply by email, remove "link" and change "now.here" to "yahoo"
    jfischer_link5809{at}now.here.com
    Jim Fischer, Jul 31, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ! aaa
    Replies:
    1
    Views:
    1,047
    ! aaa
    May 28, 2004
  2. news

    Help with data bases

    news, Nov 14, 2003, in forum: HTML
    Replies:
    4
    Views:
    427
  3. Dave Theese

    Initialization of virtual bases

    Dave Theese, Aug 24, 2003, in forum: C++
    Replies:
    1
    Views:
    328
    John Harrison
    Aug 24, 2003
  4. Dave

    Private bases

    Dave, Nov 18, 2003, in forum: C++
    Replies:
    8
    Views:
    469
    Mike Wahler
    Nov 18, 2003
  5. christopher diggins
    Replies:
    31
    Views:
    994
    Mark A. Gibbs
    Apr 9, 2004
Loading...

Share This Page