Re: Calling Class Constructor from Another Constructor

Discussion in 'C++' started by Alf P. Steinbach, Nov 30, 2007.

  1. (I'm responding to this follow-up by "anon" because the original article
    does not appear on my news-server, but it's really a reply to "ashwin".)

    * anon:
    > ashwin wrote:
    >> I was trying the following on VC++ 6.0


    That compiler is pre-standard.

    You should really upgrade to a newer compiler (newer versions of that
    compiler, sans IDE, are free).


    >> #include <iostream>
    >> struct A
    >> {
    >> A(int a)
    >> {
    >> x = a;
    >>
    >> }


    In general, prefer initializer lists to member assignments in constructors,

    A( int a ): x( a ) {}


    >> A(int a, double b)
    >>
    >> {
    >> A::A(a);
    >> y = b;
    >> }


    Not sure whether the qualification "A::" is allowed. But anyway, the
    C++ rules are designed to couple allocation with initialization
    (constructor call), so that for a class with defined constructor,
    without using low-level facilities you get both or none.

    I.e. if you allocate you get construction, and if you construct you get
    allocation.

    So what the "A(a)" does does is to create a temporary (allocation) and
    construct it, then destroy it.


    >> int x;
    >> double y;
    >> };
    >>
    >> int main()
    >> {
    >> A a(1,2.4);
    >>
    >> std::cout<<"x="<<a.x<<std::endl;
    >>
    >> return 0;
    >> }
    >>
    >> //Output
    >> x=-858993460


    Undefined behavior because x has not been initialized.


    >> What is wrong with the program ?
    >> Calling a Constructor from Another Constructor invalid in C++ ?

    >
    > To put it shortly: yes, it is invalid


    Well, the syntax "A::A(a)" may well be invalid. There's no point in
    looking up the exact rules because there's no need to use that syntax.
    Just "A(a)" is perfectly valid, it just doesn't delegate construction.

    C++0x will introduce support for constructor delegation.

    Until then there are three ways to delegate construction, in order from
    good to bad:

    * Using a base class.

    * Using an init() member function (which is mentioned by the FAQ, but
    this runs the risk of two-phase construction, it risks needless
    costly default construction, and it doesn't handle bases or members
    that can't be default-constructed).

    * Placement new (in practice this is very dangerous and limiting,
    and in theory it's in general UB to use it for delegation).

    Cheers, & hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Alf P. Steinbach, Nov 30, 2007
    #1
    1. Advertising

  2. Alf P. Steinbach

    James Kanze Guest

    On Nov 30, 10:13 am, "Alf P. Steinbach" <> wrote:
    > (I'm responding to this follow-up by "anon" because the original article
    > does not appear on my news-server, but it's really a reply to "ashwin".)


    > * anon:


    > > ashwin wrote:
    > >> I was trying the following on VC++ 6.0


    > That compiler is pre-standard.


    > You should really upgrade to a newer compiler (newer versions of that
    > compiler, sans IDE, are free).


    Even with the IDE. (It may not be complete, however. Since I
    don't usually use the IDE, I can't tell.)

    [...]
    > A( int a ): x( a ) {}


    > >> A(int a, double b)


    > >> {
    > >> A::A(a);
    > >> y = b;
    > >> }


    > Not sure whether the qualification "A::" is allowed.


    (I think it is; there's a rule about class name injection which
    means that the typename A is considered as being declared in A.
    But the rule is subtle enough that I'm not sure all compilers
    agree:).)

    > But anyway, the
    > C++ rules are designed to couple allocation with initialization
    > (constructor call), so that for a class with defined constructor,
    > without using low-level facilities you get both or none.


    > I.e. if you allocate you get construction, and if you construct you get
    > allocation.


    > So what the "A(a)" does does is to create a temporary (allocation) and
    > construct it, then destroy it.


    No. What the "A(a)" does is declare a local variable with the
    name a and the type A, using the default constructor. Since
    there is no default constructor, it shouldn't compile. (Ditto
    for A::A(a), but as I said above, I wouldn't be surprised if
    some compilers treat it incorrectly.)

    Since a is an int, he could write "A( a+0 );" to get the effect
    you describe. (Nothing like a bit of obfuscation to add to the
    fun:).) Or "static_cast< A >( a )", or "(A)( a )", or any
    other notation that can only be interpreted as an "explicit type
    conversion". But of course, in this case, that's not what he
    wants or needs either.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    James Kanze, Nov 30, 2007
    #2
    1. Advertising

  3. Alf P. Steinbach wrote:
    > (I'm responding to this follow-up by "anon" because the original article
    > does not appear on my news-server, but it's really a reply to "ashwin".)
    >
    > * anon:
    >> ashwin wrote:
    >>> I was trying the following on VC++ 6.0

    >
    > That compiler is pre-standard.
    >
    > You should really upgrade to a newer compiler (newer versions of that
    > compiler, sans IDE, are free).
    >
    >

    I am beginning to wonder if we should consider questions based on using
    VC6 as being off-topic. That compiler never was Standard conforming (or
    even close) and was released a decade ago. We are only a couple of years
    from the next release of the C++ Standard. It isn't as if there was a
    shortage of (free, as in without cost)implementations that are very
    close to the Standard (though the lack of demand for export means that
    most are not actually conforming -- export is expensive to implement and
    in the context of little demand for it most implementors have better
    things to do with their time)

    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Francis Glassborow, Nov 30, 2007
    #3
  4. * James Kanze:
    > On Nov 30, 10:13 am, "Alf P. Steinbach" <> wrote:
    >
    >>>> A(int a, double b)
    >>>>
    >>>> {
    >>>> A::A(a);
    >>>> y = b;
    >>>> }

    >
    >> Not sure whether the qualification "A::" is allowed.

    >
    > (I think it is; there's a rule about class name injection which
    > means that the typename A is considered as being declared in A.
    > But the rule is subtle enough that I'm not sure all compilers
    > agree:).)


    Hm. MSVC 7.1 compiles the original code fine. Comeau Online chokes on
    the qualification,

    Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
    Copyright 1988-2007 Comeau Computing. All rights reserved.
    MODE:strict errors C++ C++0x_extensions

    "ComeauTest.c", line 12: error: a constructor or destructor may not
    have its
    address taken
    A::A(a+0);
    ^

    1 error detected in the compilation of "ComeauTest.c".


    >> But anyway, the
    >> C++ rules are designed to couple allocation with initialization
    >> (constructor call), so that for a class with defined constructor,
    >> without using low-level facilities you get both or none.

    >
    >> I.e. if you allocate you get construction, and if you construct you get
    >> allocation.

    >
    >> So what the "A(a)" does does is to create a temporary (allocation) and
    >> construct it, then destroy it.

    >
    > No. What the "A(a)" does is declare a local variable with the
    > name a and the type A, using the default constructor. Since
    > there is no default constructor, it shouldn't compile. (Ditto
    > for A::A(a), but as I said above, I wouldn't be surprised if
    > some compilers treat it incorrectly.)


    I think you're right.

    I confused semantic knowledge (that 'a' is an int variable) with pure
    syntactical rules.

    As mentioned above, MSVC 7.1 compiles the original code, but checking
    now with Comeau Online and g++ 3.4.4, they treat as you say as a
    declaration of a local variable 'a', which conflicts with the existing
    'a' and that's what they emit diagnostics about.

    Cheers,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    Alf P. Steinbach, Nov 30, 2007
    #4
  5. Alf P. Steinbach

    James Kanze Guest

    On Nov 30, 3:55 pm, Francis Glassborow
    <> wrote:
    > Alf P. Steinbach wrote:
    > > (I'm responding to this follow-up by "anon" because the original article
    > > does not appear on my news-server, but it's really a reply to "ashwin".)


    > > * anon:
    > >> ashwin wrote:
    > >>> I was trying the following on VC++ 6.0


    > > That compiler is pre-standard.


    > > You should really upgrade to a newer compiler (newer versions of that
    > > compiler, sans IDE, are free).


    > I am beginning to wonder if we should consider questions based
    > on using VC6 as being off-topic.


    I can hardly see that as reasonable. For better of for worse,
    it continues to be widely used.

    > That compiler never was Standard conforming (or even close)
    > and was released a decade ago.


    In fact, it couldn't be standard conforming, because there was
    no standard when it was released. The name of the language was
    still C++. Neither the moderated group nor the unmoderated one
    mention standard conformance as a criteria in their charters;
    they just speak about portable, platform independent C++.

    Of course, VC++ 8 isn't standard conforming, nor is the latest
    version of g++. If your concern is portable, platform
    independent C++, you pretty much have to take more than just the
    standard into consideration anyway. If someone asks the
    classical question as to why he has undefined externals from his
    templates, because he's defined them in a source file, do we
    respond that he should just use export. That is, after all,
    what the standard says, and it will work with any standard
    conforming compiler.

    It's sad to say (it makes me very sad indeed), but ISO has
    largely become irrelevant where C and C++ are concerned.

    > We are only a couple of years from the next release of the C++
    > Standard.


    Which, for all we know, won't be respected any more than the
    current version is.

    > It isn't as if there was a shortage of (free, as in
    > without cost)implementations that are very close to the
    > Standard (though the lack of demand for export means that most
    > are not actually conforming -- export is expensive to
    > implement and in the context of little demand for it most
    > implementors have better things to do with their time)


    If there's no demand for export, it's because large projects
    still don't use templates. And in this case, demand also
    follows offer: people aren't using export because it's not
    portable, and it's not portable because people aren't using it,
    so compiler authors don't feel motivated to implement it.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
     
    James Kanze, Nov 30, 2007
    #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. Asfand Yar Qazi
    Replies:
    6
    Views:
    15,636
    jeffc
    May 17, 2004
  2. Neroku
    Replies:
    8
    Views:
    1,203
    Tor Iver Wilhelmsen
    Nov 18, 2006
  3. raunaq
    Replies:
    4
    Views:
    723
    Darryl L. Pierce
    Jan 21, 2007
  4. ali
    Replies:
    4
    Views:
    578
    David Harmon
    Mar 5, 2007
  5. Generic Usenet Account
    Replies:
    10
    Views:
    2,243
Loading...

Share This Page