Strange compiler warning

Discussion in 'C++' started by Sony Antony, Aug 13, 2003.

  1. Sony Antony

    Sony Antony Guest

    I have the following simple program in Solaris Forte compiler 5.4
    producing the warning. Though it produces the warning, it works fine
    as expected.
    This has been compiling fine without any warnings in the older 5.1
    compiler. Since the latest compiler produces a warning, it makes me
    suspecious about my own code. I still cannot find any problems with it
    though.

    It essentially produces a warning whenever a copy constructor of a
    class with a pure virtual function invokes the pure virtual function
    method on the instance that was passed to it.

    Eg : -
    class X {
    public:
    virtual void foo() = 0 ;
    X (){}
    X( X& x) { x.foo() ; }
    }

    Is this a compiler bug. Or am I wrong somewhere.
    Thanks for the help
    --sony



    quark:/home/ffdfptz/t>CC -V
    CC: Forte Developer 7 C++ 5.4 2002/03/09

    quark:/home/ffdfptz/t>CC a.C
    "a.C", line 13: Warning: Attempt to call a pure virtual function
    XXX::foo() cons
    t will always fail.
    1 Warning(s) detected.


    ///////////////////////////////////Program

    #include<iostream>
    #include<string>

    using namespace std ;

    class XXX {
    int i_ ;
    virtual int foo() const = 0 ;
    public:
    XXX(){}
    XXX( const XXX& x ) : i_( x.foo() ) {cout<<"hahha"<<i_<<endl ; }
    };

    class YY : public XXX {

    int foo() const { return 13 ; }
    public :
    YY(){}
    YY( const YY& y ) : XXX( y ) {}

    };

    int main( int argc, char* argv[] ){

    YY y ;
    YY x ( y ) ;
    return 0 ;
    }
     
    Sony Antony, Aug 13, 2003
    #1
    1. Advertisements

  2. Virtual functions are resolved statically if called from constructors
    or destructors. Calling a pure virtual function from a constructor or
    a destructor causes undefined behaviour.

    Victor
     
    Victor Bazarov, Aug 13, 2003
    #2
    1. Advertisements

  3. Sony Antony

    Gavin Deane Guest

    Comeau online compiles your code fine, with no warnings.
    http://www.comeaucomputing.com/tryitout/

    That's not an absolut guarantee of correctness, but there isn't much
    it gets wrong. Bear in mind that the compiler is allowed to warn about
    anything it likes. Perhaps they are tyring too hard to protect you.

    GJD
     
    Gavin Deane, Aug 13, 2003
    #3
  4. Sony Antony

    Tom Groszko Guest

    Just guessing since I have never used that compiler.

    When this constructor is running child classes have not yet been
    constructed, so you should not call your childrens member functions, such
    execution is I think undefined behaviour. Perhaps future versions of your
    compiler may not allow this to happen. Which foo are you expecting to run
    from here?

    Tom
     
    Tom Groszko, Aug 14, 2003
    #4
  5. Sony Antony

    Sony Antony Guest

    "> > Is this a compiler bug. Or am I wrong somewhere.
    But here the call was of a virtual function of *another* object that
    has already been completely constructed elsewhere. ( IOW the virtual
    function is not called on the object that is being constructed )
    Are you saying that in general below code will fail to invoke foo()
    polymorphically( undefined behavior ).

    class X {
    public:
    X( some_type & y ) { y.foo() ; }
    }

    --sony
     
    Sony Antony, Aug 14, 2003
    #5
  6. No, in general it's impossible to tell. I can think of a couple
    of ways to cause undefined behaviour with that.
    What's 'some_type'?
    Victor
     
    Victor Bazarov, Aug 14, 2003
    #6
  7. Sony Antony

    David White Guest

    I think it's a compiler bug, caused by not distinguishing between the object
    passed in and the object being constructed.

    DW
     
    David White, Aug 14, 2003
    #7
  8. Sony Antony

    Sony Antony Guest

    I dont understand. I have a completely constructed object ( of
    arbitrary type some_type below ). My understanding is that no matter
    what once the object has been constructed completely, it should act
    polymorphically. It should act
    polymorphic even if the method is invoked within another object's
    constructor.

    Like the case below y is a completely constructed object. When I call
    its foo(), where is the undefined behavior. The fact that I m calling
    it inside X's constructor should not matter at all right.

    Now in the original case both X and some_type happened to be of the
    same type.

    --sony
     
    Sony Antony, Aug 14, 2003
    #8
  9. Sony Antony

    David White Guest

    But it's an inappropriate and misleading warning isn't it? As the OP says,
    there's no reason to believe that the object being copied is not a fully
    constructed object. I suspect that if the code looked like this:

    class X {
    public:
    virtual void foo() = 0 ;
    X (){}
    X( X& x) { foo() ; }
    }

    the compiler would also give a warning, not an error, even though it can
    tell that this can't work. I think that's the warning it thinks it's giving
    in the x.foo() case.
    Can 'x' be in any state to be copied when it reaches the copy constructor?
    This is where the warning ought to be :)

    DW
     
    David White, Aug 14, 2003
    #9
  10. It CAN'T tell. That's the point. You are allowed to have a body
    of 'virtual void foo() = 0' elsewhere. If such body is provided,
    the call would be OK. Try it:

    struct X {
    virtual void foo() = 0;
    X() { foo(); }
    };

    #include <iostream>
    void X::foo() {
    std::cout << "Gotcha!\n";
    }

    struct Y : X {
    void foo() {}
    };

    int main() {
    Y y;
    return 0;
    }
    Who said it was copying it? It's a parameterised constructor.
    Well, yes, here too. I actually think that the more warnings
    the better.

    Victor
     
    Victor Bazarov, Aug 14, 2003
    #10
  11. Sony Antony

    David White Guest

    Oops. That's what I've telling other people recently. Okay, a warning is
    appropriate in the above case, so forget that, but I still find it hard to
    believe that the compiler warns in the x.foo() case because of the remote
    possibility that x has not yet been constructed.

    DW
     
    David White, Aug 14, 2003
    #11
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.