Problems when giving default value for 'const auto_ptr &' argument

Discussion in 'C++' started by Rein Anders Apeland, Sep 14, 2005.

  1. Consider the following working code:



    #include <memory>
    #include <iostream>

    void print_ptr( const std::auto_ptr< int > & thePtr =
    std::auto_ptr< int >() )
    {
    std::cout << "Ptr address: " << thePtr.get() << std::endl;
    }

    int main()
    {
    std::auto_ptr< int > somePtr( new int );
    print_ptr( somePtr );
    print_ptr();
    return 0;
    }




    Using GCC 3.3.4 it compiles without warning.

    Using GCC 4.0.2 it gives the following errors:

    foo.cpp: In function ‘int main()’:
    foo.cpp:15: error: no matching function for call to
    ‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>)’
    /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    ++/4.0.2/memory:349: note: candidates are:
    std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = int]
    /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    ++/4.0.2/memory:212: note:
    std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = int, _Tp
    = int]
    /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    ++/4.0.2/memory:199: note:
    std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = int]
    foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
    std::auto_ptr<int>&)’



    It appears that having a default value of 'std::auto_ptr<T>()' to
    a parameter of type 'const std::auto_ptr<T> &' is not allowed in
    GCC 4.0.2. Is there something in the C++ standard that is enforced in
    4.0.2 and not in 3.3.4, or is it purely compiler-specific.

    Does it have anything to do with the parameter being a reference?


    --
    Mvh / Regards
    Rein Anders Apeland
    MIVU Solutions
    Rein Anders Apeland, Sep 14, 2005
    #1
    1. Advertising

  2. Rein Anders Apeland

    Kanenas Guest

    On Wed, 14 Sep 2005 13:56:13 +0200, Rein Anders Apeland
    <> wrote:

    >Consider the following working code:
    >
    >#include <memory>
    >#include <iostream>
    >
    >void print_ptr( const std::auto_ptr< int > & thePtr =
    > std::auto_ptr< int >() )
    >{

    [...]
    > print_ptr();
    > return 0;
    >}
    >
    >Using GCC 3.3.4 it compiles without warning.
    >
    >Using GCC 4.0.2 it gives the following errors:
    >
    >foo.cpp: In function ‘int main()’:
    >foo.cpp:15: error: no matching function for call to
    >‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>)’


    I'm assuming line 15 is "print_ptr();".

    >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    >++/4.0.2/memory:349: note: candidates are:
    >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = int]
    >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    >++/4.0.2/memory:212: note:
    >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = int, _Tp
    >= int]
    >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    >++/4.0.2/memory:199: note:
    >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = int]
    >foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
    >std::auto_ptr<int>&)’
    >
    >
    >
    >It appears that having a default value of 'std::auto_ptr<T>()' to
    >a parameter of type 'const std::auto_ptr<T> &' is not allowed in
    >GCC 4.0.2. Is there something in the C++ standard that is enforced in
    >4.0.2 and not in 3.3.4, or is it purely compiler-specific.
    >

    I'm reading an old standard, but it certainly allows temporaries to be
    bound to references (section 12.2.5). I couldn't think of/find any
    restrictions on using temporaries which would apply in this case. I
    expect the responsibility lies with GCC 4.0.2.

    >Does it have anything to do with the parameter being a reference?


    Based on the error message, no. It has to do with GCC not using
    pass-by-reference semantics for the temporary when invoking
    std::auto_ptr's (copy) constructor even though GCC could. As to why
    GCC 4.0.2 is trying to pass the temporary to the constructor rather
    than binding the reference to the temporary (as 3.3.4 does), I don't
    know. Perhaps if GCC 4.0.2 would bind the temporary to a reference it
    wouldn't be trying to invoke the constructor with the temporary during
    thePtr's initialization.

    If you're ever curious about a question of the form "Does it have
    anything to do with x being y?", try changing x to something related
    to y.
    Kanenas, Sep 15, 2005
    #2
    1. Advertising

  3. Re: Problems when giving default value for 'const auto_ptr &'argument

    On Wed, 2005-09-14 at 18:36 -0700, Kanenas wrote:
    > On Wed, 14 Sep 2005 13:56:13 +0200, Rein Anders Apeland
    > <> wrote:
    >
    > >Consider the following working code:
    > >
    > >#include <memory>
    > >#include <iostream>
    > >
    > >void print_ptr( const std::auto_ptr< int > & thePtr =
    > > std::auto_ptr< int >() )
    > >{

    > [...]
    > > print_ptr();
    > > return 0;
    > >}
    > >
    > >Using GCC 3.3.4 it compiles without warning.
    > >
    > >Using GCC 4.0.2 it gives the following errors:
    > >
    > >foo.cpp: In function ‘int main()’:
    > >foo.cpp:15: error: no matching function for call to
    > >‘std::auto_ptr<int>::auto_ptr(std::auto_ptr<int>)’

    >
    > I'm assuming line 15 is "print_ptr();".
    >
    > >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    > >++/4.0.2/memory:349: note: candidates are:
    > >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = int]
    > >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    > >++/4.0.2/memory:212: note:
    > >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&) [with _Tp1 = int, _Tp
    > >= int]
    > >/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../include/c
    > >++/4.0.2/memory:199: note:
    > >std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = int]
    > >foo.cpp:6: error: in passing argument 1 of ‘void print_ptr(const
    > >std::auto_ptr<int>&)’
    > >
    > >
    > >
    > >It appears that having a default value of 'std::auto_ptr<T>()' to
    > >a parameter of type 'const std::auto_ptr<T> &' is not allowed in
    > >GCC 4.0.2. Is there something in the C++ standard that is enforced in
    > >4.0.2 and not in 3.3.4, or is it purely compiler-specific.
    > >

    > I'm reading an old standard, but it certainly allows temporaries to be
    > bound to references (section 12.2.5). I couldn't think of/find any
    > restrictions on using temporaries which would apply in this case. I
    > expect the responsibility lies with GCC 4.0.2.
    >
    > >Does it have anything to do with the parameter being a reference?

    >
    > Based on the error message, no. It has to do with GCC not using
    > pass-by-reference semantics for the temporary when invoking
    > std::auto_ptr's (copy) constructor even though GCC could. As to why
    > GCC 4.0.2 is trying to pass the temporary to the constructor rather
    > than binding the reference to the temporary (as 3.3.4 does), I don't
    > know. Perhaps if GCC 4.0.2 would bind the temporary to a reference it
    > wouldn't be trying to invoke the constructor with the temporary during
    > thePtr's initialization.


    In GCC 4.0.2, passing a temporary std::string() to a parameter of
    type 'const std::string &' works fine. What could be the difference
    between std::string and std::auto_ptr that triggers the error message?


    >
    > If you're ever curious about a question of the form "Does it have
    > anything to do with x being y?", try changing x to something related
    > to y.

    --
    Mvh / Regards
    Rein Anders Apeland
    MIVU Solutions
    Rein Anders Apeland, Sep 15, 2005
    #3
  4. Rein Anders Apeland

    Pete C Guest

    > As to why
    > GCC 4.0.2 is trying to pass the temporary to the constructor rather
    > than binding the reference to the temporary (as 3.3.4 does), I don't
    > know.


    When initialising a const reference to an rvalue (which we are in this
    case), the compiler may either:

    a) Bind the reference directly to the object that the rvalue
    represents, or
    b) Construct a temporary const object from the rvalue, and bind the
    reference to the temporary.

    The choice is implementation-defined, but the standard says that the
    constructor that would be used in (b) must be available anyway.
    However for auto_ptr, such a constructor is *not* available, because
    auto_ptr's copy constructor takes a non-const reference (to which an
    rvalue cannot be bound). So the new error is correct. See section
    8.5.3.5 of the Standard for gory details.

    Incidentally, the Microsoft implementation I'm currently looking at
    (incorrectly) provides an auto_ptr which takes a const reference.
    Plenty of code has been written that relies on this, sadly.

    The difference with std::string (as questioned elsewhere on this
    thread), is that std::string *does* provide a copy constructor from a
    const reference - so (a) and (b) above are satisfied.
    Pete C, Sep 15, 2005
    #4
  5. Re: Problems when giving default value for 'const auto_ptr &'argument

    On Thu, 2005-09-15 at 07:15 -0700, Pete C wrote:
    > > As to why
    > > GCC 4.0.2 is trying to pass the temporary to the constructor rather
    > > than binding the reference to the temporary (as 3.3.4 does), I don't
    > > know.

    >
    > When initialising a const reference to an rvalue (which we are in this
    > case), the compiler may either:
    >
    > a) Bind the reference directly to the object that the rvalue
    > represents, or
    > b) Construct a temporary const object from the rvalue, and bind the
    > reference to the temporary.
    >
    > The choice is implementation-defined, but the standard says that the
    > constructor that would be used in (b) must be available anyway.
    > However for auto_ptr, such a constructor is *not* available, because
    > auto_ptr's copy constructor takes a non-const reference (to which an
    > rvalue cannot be bound). So the new error is correct. See section
    > 8.5.3.5 of the Standard for gory details.
    >
    > Incidentally, the Microsoft implementation I'm currently looking at
    > (incorrectly) provides an auto_ptr which takes a const reference.
    > Plenty of code has been written that relies on this, sadly.
    >
    > The difference with std::string (as questioned elsewhere on this
    > thread), is that std::string *does* provide a copy constructor from a
    > const reference - so (a) and (b) above are satisfied.


    Thanks a lot! I now see why GCC 4.0.2 acts the way it does, and why
    it must be that way.

    >

    --
    Mvh / Regards
    Rein Anders Apeland
    MIVU Solutions
    Rein Anders Apeland, Sep 15, 2005
    #5
    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. Siemel Naran

    auto_ptr<Derived> to auto_ptr<Base>

    Siemel Naran, Jan 10, 2005, in forum: C++
    Replies:
    2
    Views:
    1,533
    Dave Rahardja
    Jan 11, 2005
  2. LaundroMat
    Replies:
    50
    Views:
    937
    Hendrik van Rooyen
    Oct 14, 2006
  3. Javier
    Replies:
    2
    Views:
    541
    James Kanze
    Sep 4, 2007
  4. sixteenmillion

    The giving that keeps on giving

    sixteenmillion, Nov 19, 2007, in forum: C Programming
    Replies:
    0
    Views:
    413
    sixteenmillion
    Nov 19, 2007
  5. Sousuke
    Replies:
    9
    Views:
    1,126
    Bart van Ingen Schenau
    Mar 16, 2010
Loading...

Share This Page