Q: wrong const data type in constructor

Discussion in 'C++' started by Claudius, May 10, 2010.

  1. Claudius

    Claudius Guest

    Hello,

    in the following example, is it correct that the compiler sets the
    'this'-pointer to type (const A *) in both calls of the copy-
    constructor? (I compiled it with g++-4.3.4)
    I had expected (A *).

    class A {
    public:
    A( A & a ) {
    int i = 2;
    }

    A() {}

    int i;
    };

    int main( void ) {

    A a;
    A b( a ); //this = const A *, ???
    const A c( b ); //this = const A *, ok

    return 1;
    }

    So it is not possible to recognize within the copy constructor whether
    a const object is to be created or not.
     
    Claudius, May 10, 2010
    #1
    1. Advertising

  2. On May 10, 6:42 am, Claudius <> wrote:
    > Hello,
    >
    > in the following example, is it correct that the compiler sets the
    > 'this'-pointer to type (const A *) in both calls of the copy-
    > constructor?  (I compiled it with g++-4.3.4)
    > I had expected (A *).
    >
    > class A {
    > public:
    >     A( A & a ) {
    >         int i = 2;
    >     }
    >
    >     A() {}
    >
    >     int i;
    >
    > };
    >
    > int main( void ) {
    >
    >     A a;
    >     A b( a );           //this = const A *, ???
    >     const A c( b );     //this = const A *, ok
    >
    >     return 1;
    >
    > }
    >
    > So it is not possible to recognize within the copy constructor whether
    > a const object is to be created or not.


    Hi

    The type of this pointer for class X is X* inside non-static non-
    const
    member function and inside const member function, it will be const X*.
    this pointer is used about calling const/non-const member functions

    class A {
    // ...
    public:
    int Get() const { return i; }
    void Set(int ii) /* non-const */ { i = ii; }
    };

    A a;
    const ca;
    a.Get(); // OK
    a.Set(1); // OK

    ca.Get(); // OK
    ca.Set(2); // error

    I think for const object, the this is pointer to const data,
    but for non-const object it depends to the member function.

    Regards,
    -- Saeed Amrollhi
     
    Saeed Amrollahi, May 10, 2010
    #2
    1. Advertising

  3. Claudius

    Salt_Peter Guest

    On May 9, 10:42 pm, Claudius <> wrote:
    > Hello,
    >
    > in the following example, is it correct that the compiler sets the
    > 'this'-pointer to type (const A *) in both calls of the copy-
    > constructor?  (I compiled it with g++-4.3.4)
    > I had expected (A *).
    >
    > class A {
    > public:
    >     A( A & a ) {
    >         int i = 2;
    >     }
    >
    >     A() {}
    >
    >     int i;
    >
    > };
    >
    > int main( void ) {
    >
    >     A a;
    >     A b( a );           //this = const A *, ???
    >     const A c( b );     //this = const A *, ok
    >
    >     return 1;
    >
    > }
    >
    > So it is not possible to recognize within the copy constructor whether
    > a const object is to be created or not.


    You are constructing objects from scratch.
    Whether these are const or not is irrelevant.
    What you are seeing is compiler optimization.

    use initialization lists.
    Its one of the cornerstones of C++.
    Also, never ever leave a member uninitialized.
    That, in effect, is the only issue you need to pay attention-to about
    const objects.

    class A
    {
    const int i;
    public:
    A() : i(1) { }
    A( const A& copy ) : i(copy.i + 1) { }
    };

    Incidentally, if you where to use your A( A & a ) copy-ctor in the
    following statement it would fail:
    A a = A(); // tries to copy a temporary object
     
    Salt_Peter, May 10, 2010
    #3
  4. Claudius <> writes:

    > Hello,
    >
    > in the following example, is it correct that the compiler sets the
    > 'this'-pointer to type (const A *) in both calls of the copy-
    > constructor? (I compiled it with g++-4.3.4)
    > I had expected (A *).
    >
    > class A {
    > public:
    > A( A & a ) {
    > int i = 2;
    > }
    >
    > A() {}
    >
    > int i;
    > };
    >
    > int main( void ) {
    >
    > A a;
    > A b( a ); //this = const A *, ???
    > const A c( b ); //this = const A *, ok
    >
    > return 1;
    > }
    >
    > So it is not possible to recognize within the copy constructor whether
    > a const object is to be created or not.


    Can I ask, how exactly you are determining that the this pointer is set
    to const A * in both copy-ctor calls? I ask this because I'm getting A
    * const in both instances.

    10:58:34 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $gcc -O0 -gdwarf-2 -g3 -c
    const_this.cpp

    10:58:38 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $g++ -Wl,--enable-auto-import -static
    -o const_this const_this.o

    10:58:47 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $gdb ./const_this
    GNU gdb (GDB) 7.0.50.20100128-cvs
    ...
    Reading symbols from
    /cygdrive/d/CPPProjects/CLCPP/const_this...done.
    (gdb) break const_this.cpp:15
    Breakpoint 1 at 0x4010fa: file const_this.cpp, line 15.
    (gdb) break const_this.cpp:16
    Breakpoint 2 at 0x40110e: file const_this.cpp, line 16.
    (gdb) run
    Starting program: /cygdrive/d/CPPProjects/CLCPP/const_this
    [New Thread 7204.0x1c28]
    [New Thread 7204.0x1c2c]

    Breakpoint 1, main () at const_this.cpp:15
    15 A b( a ); // this = const A *, ???
    (gdb) step
    A (this=0x22ccf8, a=...) at const_this.cpp:4
    4 int i = 1;
    (gdb) print this
    $1 = (A * const) 0x22ccf8
    (gdb) continue
    Continuing.

    Breakpoint 2, main () at const_this.cpp:16
    16 const A c( b ); // this = const A *, ok
    (gdb) step
    A (this=0x22ccf4, a=...) at const_this.cpp:4
    4 int i = 1;
    (gdb) print this
    $2 = (A * const) 0x22ccf4
    (gdb)

    It is only if I add something like a const member function that I get a
    pointer to const, such as:

    Breakpoint 1, main () at const_this.cpp:19
    19 a.get();
    (gdb) step
    A::get (this=0x22ccfc) at const_this.cpp:9
    9 int get() const { return i; }
    (gdb) print this
    $1 = (const A * const) 0x22ccfc
    (gdb)

    Regards

    Paul Bibbings
     
    Paul Bibbings, May 10, 2010
    #4
  5. Claudius

    Claudius Guest

    On 10 Mai, 08:06, Salt_Peter <> wrote:
    > On May 9, 10:42 pm, Claudius <> wrote:
    >
    >
    >
    > > Hello,

    >
    > > in the following example, is it correct that the compiler sets the
    > > 'this'-pointer to type (const A *) in both calls of the copy-
    > > constructor?  (I compiled it with g++-4.3.4)
    > > I had expected (A *).

    >
    > > class A {
    > > public:
    > >     A( A & a ) {
    > >         int i = 2;
    > >     }

    >
    > >     A() {}

    >
    > >     int i;

    >
    > > };

    >
    > > int main( void ) {

    >
    > >     A a;
    > >     A b( a );           //this = const A *, ???
    > >     const A c( b );     //this = const A *, ok

    >
    > >     return 1;

    >
    > > }

    >
    > > So it is not possible to recognize within the copy constructor whether
    > > a const object is to be created or not.

    >
    > You are constructing objects from scratch.
    > Whether these are const or not is irrelevant.
    > What you are seeing is compiler optimization.
    >
    > use initialization lists.
    > Its one of the cornerstones of C++.
    > Also, never ever leave a member uninitialized.
    > That, in effect, is the only issue you need to pay attention-to about
    > const objects.
    >
    > class A
    > {
    >     const int i;
    >   public:
    >     A() : i(1) { }
    >     A( const A& copy ) : i(copy.i + 1) { }
    >
    > };
    >
    > Incidentally, if you where to use your A( A & a ) copy-ctor in the
    > following statement it would fail:
    > A a = A(); // tries to copy a temporary object


    Is it possible to disable the corresponding compiler optimization so
    that within the copy-ctor a decision is possible whether a const or
    non-const object is to be created?
     
    Claudius, May 10, 2010
    #5
  6. Claudius

    Claudius Guest

    On 10 Mai, 12:06, Paul Bibbings <> wrote:
    > Claudius <> writes:
    > > Hello,

    >
    > > in the following example, is it correct that the compiler sets the
    > > 'this'-pointer to type (const A *) in both calls of the copy-
    > > constructor?  (I compiled it with g++-4.3.4)
    > > I had expected (A *).

    >
    > > class A {
    > > public:
    > >     A( A & a ) {
    > >         int i = 2;
    > >     }

    >
    > >     A() {}

    >
    > >     int i;
    > > };

    >
    > > int main( void ) {

    >
    > >     A a;
    > >     A b( a );           //this = const A *, ???
    > >     const A c( b );     //this = const A *, ok

    >
    > >     return 1;
    > > }

    >
    > > So it is not possible to recognize within the copy constructor whether
    > > a const object is to be created or not.

    >
    > Can I ask, how exactly you are determining that the this pointer is set
    > to const A * in both copy-ctor calls?  I ask this because I'm getting A
    > * const in both instances.
    >
    >    10:58:34 Paul Bibbings@JIJOU
    >    /cygdrive/d/CPPProjects/CLCPP $gcc -O0 -gdwarf-2 -g3 -c
    >       const_this.cpp
    >
    >    10:58:38 Paul Bibbings@JIJOU
    >    /cygdrive/d/CPPProjects/CLCPP $g++ -Wl,--enable-auto-import -static
    >       -o const_this const_this.o
    >
    >    10:58:47 Paul Bibbings@JIJOU
    >    /cygdrive/d/CPPProjects/CLCPP $gdb ./const_this
    >    GNU gdb (GDB) 7.0.50.20100128-cvs
    >    ...
    >    Reading symbols from
    >       /cygdrive/d/CPPProjects/CLCPP/const_this...done.
    >    (gdb) break const_this.cpp:15
    >    Breakpoint 1 at 0x4010fa: file const_this.cpp, line 15.
    >    (gdb) break const_this.cpp:16
    >    Breakpoint 2 at 0x40110e: file const_this.cpp, line 16.
    >    (gdb) run
    >    Starting program: /cygdrive/d/CPPProjects/CLCPP/const_this
    >    [New Thread 7204.0x1c28]
    >    [New Thread 7204.0x1c2c]
    >
    >    Breakpoint 1, main () at const_this.cpp:15
    >    15         A b( a );           // this = const A *, ???
    >    (gdb) step
    >    A (this=0x22ccf8, a=...) at const_this.cpp:4
    >    4             int i = 1;
    >    (gdb) print this
    >    $1 = (A * const) 0x22ccf8
    >    (gdb) continue
    >    Continuing.
    >
    >    Breakpoint 2, main () at const_this.cpp:16
    >    16         const A c( b );     // this = const A *, ok
    >    (gdb) step
    >    A (this=0x22ccf4, a=...) at const_this.cpp:4
    >    4             int i = 1;
    >    (gdb) print this
    >    $2 = (A * const) 0x22ccf4
    >    (gdb)
    >
    > It is only if I add something like a const member function that I get a
    > pointer to const, such as:
    >
    >    Breakpoint 1, main () at const_this.cpp:19
    >    19         a.get();
    >    (gdb) step
    >    A::get (this=0x22ccfc) at const_this.cpp:9
    >    9          int get() const { return i; }
    >    (gdb) print this
    >    $1 = (const A * const) 0x22ccfc
    >    (gdb)
    >
    > Regards
    >
    > Paul Bibbings


    You are right, this is a 'A * const'.
    I started the small test program within the insight debugger (gdb-
    based).
    In the other calls however, it is always 'A * const' even if a non-
    const object is to be created.
     
    Claudius, May 10, 2010
    #6
  7. On 5/9/2010 10:42 PM, Claudius wrote:
    >[..]
    > So it is not possible to recognize within the copy constructor whether
    > a const object is to be created or not.


    Inside any constructor it's impossible to recognize. Until the moment
    the constructor's body finishes executing, the object is effectively
    under construction and cannot be considered const. IIRC, of course.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, May 10, 2010
    #7
  8. Claudius <> writes:

    > On 10 Mai, 12:06, Paul Bibbings <> wrote:
    >> Claudius <> writes:
    >> > Hello,

    >>
    >> > in the following example, is it correct that the compiler sets the
    >> > 'this'-pointer to type (const A *) in both calls of the copy-
    >> > constructor?  (I compiled it with g++-4.3.4)
    >> > I had expected (A *).

    >>
    >> > class A {
    >> > public:
    >> >     A( A & a ) {
    >> >         int i = 2;
    >> >     }

    >>
    >> >     A() {}

    >>
    >> >     int i;
    >> > };

    >>
    >> > int main( void ) {

    >>
    >> >     A a;
    >> >     A b( a );           //this = const A *, ???
    >> >     const A c( b );     //this = const A *, ok

    >>
    >> >     return 1;
    >> > }

    >>
    >> > So it is not possible to recognize within the copy constructor whether
    >> > a const object is to be created or not.

    >>
    >> Can I ask, how exactly you are determining that the this pointer is set
    >> to const A * in both copy-ctor calls?  I ask this because I'm getting A
    >> * const in both instances.


    <snip />

    > You are right, this is a 'A * const'.
    > I started the small test program within the insight debugger (gdb-
    > based).
    > In the other calls however, it is always 'A * const' even if a non-
    > const object is to be created.


    What I can't understand, though, is *why* the gcc/gdb combination is
    reporting the top-level const when, as the Standard says:

    [expr.prim] §5.1/3
    "The keyword this names a pointer to the object for which a nonstatic
    member function (9.3.2) is invoked. [...] The type of the expression
    is a pointer to the function's class (9.3.2), possibly with
    cv-qualifiers on the class type. The expression is an rvalue."

    and this is clarified in §9.3.2, in pretty much the same terms as Saeed
    used:

    [class.this] §9.3.2/1
    "In the body of a nonstatic (9.3) member function, the keyword this
    is a non-lvalue expression whose value is the address of the object
    for which the function is called. The type of this in a member
    function of class X is X*. If the member function is declared const,
    the type of this is const X*..."

    So, from the above, I would have expected A* and const A* where we found
    A* const and const A* const.

    Obviously this is a `special' kind of pointer in some sense, and can't
    be assigned to in any circumstance in user code, as far as I am aware.
    But it doesn't appear that it is const either.

    Curious!

    Regards

    Paul Bibbings
     
    Paul Bibbings, May 10, 2010
    #8
  9. Claudius

    Kai-Uwe Bux Guest

    Victor Bazarov wrote:

    > On 5/9/2010 10:42 PM, Claudius wrote:
    >>[..]
    >> So it is not possible to recognize within the copy constructor whether
    >> a const object is to be created or not.

    >
    > Inside any constructor it's impossible to recognize. Until the moment
    > the constructor's body finishes executing, the object is effectively
    > under construction and cannot be considered const. IIRC, of course.


    You recall correctly. It's in [12.1/4].

    BTW, the same is true for destructors [12.4/2].


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, May 10, 2010
    #9
  10. Claudius

    Bo Persson Guest

    Claudius wrote:
    > On 10 Mai, 08:06, Salt_Peter <> wrote:
    >> On May 9, 10:42 pm, Claudius <> wrote:
    >>
    >>
    >>
    >>> Hello,

    >>
    >>> in the following example, is it correct that the compiler sets the
    >>> 'this'-pointer to type (const A *) in both calls of the copy-
    >>> constructor? (I compiled it with g++-4.3.4)
    >>> I had expected (A *).

    >>
    >>> class A {
    >>> public:
    >>> A( A & a ) {
    >>> int i = 2;
    >>> }

    >>
    >>> A() {}

    >>
    >>> int i;

    >>
    >>> };

    >>
    >>> int main( void ) {

    >>
    >>> A a;
    >>> A b( a ); //this = const A *, ???
    >>> const A c( b ); //this = const A *, ok

    >>
    >>> return 1;

    >>
    >>> }

    >>
    >>> So it is not possible to recognize within the copy constructor
    >>> whether a const object is to be created or not.

    >>
    >> You are constructing objects from scratch.
    >> Whether these are const or not is irrelevant.
    >> What you are seeing is compiler optimization.
    >>
    >> use initialization lists.
    >> Its one of the cornerstones of C++.
    >> Also, never ever leave a member uninitialized.
    >> That, in effect, is the only issue you need to pay attention-to
    >> about const objects.
    >>
    >> class A
    >> {
    >> const int i;
    >> public:
    >> A() : i(1) { }
    >> A( const A& copy ) : i(copy.i + 1) { }
    >>
    >> };
    >>
    >> Incidentally, if you where to use your A( A & a ) copy-ctor in the
    >> following statement it would fail:
    >> A a = A(); // tries to copy a temporary object

    >
    > Is it possible to disable the corresponding compiler optimization so
    > that within the copy-ctor a decision is possible whether a const or
    > non-const object is to be created?


    No. Why should creating an object be different for these cases?


    Bo Persson
     
    Bo Persson, May 10, 2010
    #10
  11. Claudius

    Claudius Guest

    On 10 Mai, 17:56, "Bo Persson" <> wrote:
    > Claudius wrote:
    > > On 10 Mai, 08:06, Salt_Peter <> wrote:
    > >> On May 9, 10:42 pm, Claudius <> wrote:

    >
    > >>> Hello,

    >
    > >>> in the following example, is it correct that the compiler sets the
    > >>> 'this'-pointer to type (const A *) in both calls of the copy-
    > >>> constructor? (I compiled it with g++-4.3.4)
    > >>> I had expected (A *).

    >
    > >>> class A {
    > >>> public:
    > >>> A( A & a ) {
    > >>> int i = 2;
    > >>> }

    >
    > >>> A() {}

    >
    > >>> int i;

    >
    > >>> };

    >
    > >>> int main( void ) {

    >
    > >>> A a;
    > >>> A b( a ); //this = const A *, ???
    > >>> const A c( b ); //this = const A *, ok

    >
    > >>> return 1;

    >
    > >>> }

    >
    > >>> So it is not possible to recognize within the copy constructor
    > >>> whether a const object is to be created or not.

    >
    > >> You are constructing objects from scratch.
    > >> Whether these are const or not is irrelevant.
    > >> What you are seeing is compiler optimization.

    >
    > >> use initialization lists.
    > >> Its one of the cornerstones of C++.
    > >> Also, never ever leave a member uninitialized.
    > >> That, in effect, is the only issue you need to pay attention-to
    > >> about const objects.

    >
    > >> class A
    > >> {
    > >> const int i;
    > >> public:
    > >> A() : i(1) { }
    > >> A( const A& copy ) : i(copy.i + 1) { }

    >
    > >> };

    >
    > >> Incidentally, if you where to use your A( A & a ) copy-ctor in the
    > >> following statement it would fail:
    > >> A a = A(); // tries to copy a temporary object

    >
    > > Is it possible to disable the corresponding compiler optimization so
    > > that within the copy-ctor a decision is possible whether a const or
    > > non-const object is to be created?

    >
    > No. Why should creating an object be different for these cases?
    >
    > Bo Persson


    In the copy-ctor I'd like to reference the data structures of the
    other object instead of copying them.
    Then, with reference counting pointers it is possible to use the copy-
    ctor to return local objects with data structures on the heap by value
    as it were 'by reference'.

    BUT this breaks const-correctness if it is not possible to treat it
    correctly. For an example see the array class in the blitz library.
     
    Claudius, May 11, 2010
    #11
    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. p|OtrEk

    const type& and type const&

    p|OtrEk, Jul 17, 2005, in forum: C++
    Replies:
    6
    Views:
    410
    Ben Pope
    Jul 17, 2005
  2. Replies:
    11
    Views:
    1,141
  3. Javier
    Replies:
    2
    Views:
    600
    James Kanze
    Sep 4, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,313
  5. paulo
    Replies:
    9
    Views:
    732
    James Kanze
    Mar 6, 2009
Loading...

Share This Page