Questionable compiler warning

Discussion in 'C++' started by Thomas Heinz, Jul 8, 2004.

  1. Thomas Heinz

    Thomas Heinz Guest

    Hi

    Consider the following program.

    class T
    {
    int b, a;
    T(int a, int b) : a(a), b(b) {}
    };

    g++ -Wall -c test.cc produces the following warning.

    test.cc: In constructor `T::T(int, int)':
    test.cc:3: Warnung: `T::a' will be initialized after
    test.cc:3: Warnung: `int T::b'
    test.cc:4: Warnung: when initialized here


    Obviously, g++ likes the initialization order to be
    the same as the declaration order of the corresponding
    variables. Does anyone know whether/why it is critical
    for them to have the same order?

    Thanks for your help.


    Regards,

    Thomas
     
    Thomas Heinz, Jul 8, 2004
    #1
    1. Advertising

  2. "Thomas Heinz" <> wrote in message
    news:ccjnal$5e55q$-saarland.de...
    > Hi
    >
    > Consider the following program.
    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(b) {}
    > };
    >
    > g++ -Wall -c test.cc produces the following warning.
    >
    > test.cc: In constructor `T::T(int, int)':
    > test.cc:3: Warnung: `T::a' will be initialized after
    > test.cc:3: Warnung: `int T::b'
    > test.cc:4: Warnung: when initialized here
    >
    >
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables. Does anyone know whether/why it is critical
    > for them to have the same order?


    It isn't, but some people wrongly assume that the order of initalisation is
    the same as the order in the initialisation list. So I would imagine the
    reason for the warning is just to make sure people don't make that mistake.

    john
     
    John Harrison, Jul 8, 2004
    #2
    1. Advertising

  3. Thomas Heinz

    Thomas Heinz Guest

    Hi John

    You wrote:
    > It isn't, but some people wrongly assume that the order of initalisation is
    > the same as the order in the initialisation list. So I would imagine the
    > reason for the warning is just to make sure people don't make that mistake.


    There is a misunderstanding. My question should rather be:

    "Obviously, g++ likes the initialization order to be
    the same as the declaration order of the corresponding
    members." (not variables in the init. list).

    However, I think one reason why the initialization order is
    fixed by some means is that there can only be one destruction
    order.


    Regards,

    Thomas
     
    Thomas Heinz, Jul 8, 2004
    #3
  4. Thomas Heinz wrote:
    > Hi John
    >
    > You wrote:
    >
    >> It isn't, but some people wrongly assume that the order of
    >> initalisation is
    >> the same as the order in the initialisation list. So I would imagine the
    >> reason for the warning is just to make sure people don't make that
    >> mistake.

    >
    >
    > There is a misunderstanding. My question should rather be:
    >
    > "Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > members." (not variables in the init. list).
    >
    > However, I think one reason why the initialization order is
    > fixed by some means is that there can only be one destruction
    > order.


    Yes, but that's not the essence of your statement, nor is it the essence
    of John's reply. The reason for the warning is to _remind_ the user that
    the order [of initialisation] is going to be the same as the declaration,
    and not the order of initialisers in the list.

    It's not that g++ "likes" it to be the same, it's more in line with g++
    trying to keep the user from making the mistake. If g++ _liked_ it to be
    specific, then it would probably issue an error instead of a warning.

    Sorry to butt in on the conversation, just thought I'd add my $0.02...

    V
     
    Victor Bazarov, Jul 8, 2004
    #4
  5. Thomas Heinz wrote:
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(b) {}
    > };
    >
    > g++ -Wall -c test.cc produces the following warning.
    >
    > test.cc: In constructor `T::T(int, int)':
    > test.cc:3: Warnung: `T::a' will be initialized after
    > test.cc:3: Warnung: `int T::b'
    > test.cc:4: Warnung: when initialized here
    >
    >
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables. Does anyone know whether/why it is critical
    > for them to have the same order?

    The definite initialization order is followed by g++, not just because
    it likes, but because the C++ standard says so.

    Here is an excerpt from the C++ standard for the same:

    <C++STD>
    12.6.2 - Initializing bases and members [class.base.init]
    5.
    Then, nonstatic data members shall be initialized in the order they were
    declared in the class definition (again regardless of the order of the
    mem-initializers).
    </C++STD>

    --
    Nithyanandham M
    SIEMENS, Bangalore, India.

    (Please remove 'AtoZ' from my address when replying by mail)
     
    Nithyanandham M, Jul 8, 2004
    #5
  6. "Thomas Heinz" <> wrote in message
    news:ccjnal$5e55q$-saarland.de...
    > Hi
    >
    > Consider the following program.
    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(b) {}
    > };
    >
    > g++ -Wall -c test.cc produces the following warning.
    >
    > test.cc: In constructor `T::T(int, int)':
    > test.cc:3: Warnung: `T::a' will be initialized after
    > test.cc:3: Warnung: `int T::b'
    > test.cc:4: Warnung: when initialized here
    >
    >
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables. Does anyone know whether/why it is critical
    > for them to have the same order?


    As pointed out elsewhere, the standard calls for initialization in
    declaration order. This is to allow for use of one variable in initializing
    another. Suppose b was always (3*a) more than the value provided for b
    (fancy encryption!). Your code might be:

    ....
    T(int a, int b) : a(a), b(a*3 + b) {}
    ....
    Can you see that this won't work because b will be initialized first, using
    an uninitialized a? That's why the warning was issued.
    Changing the order in the declaration would allow this initialization list
    to work properly.
    --
    Gary
     
    Gary Labowitz, Jul 8, 2004
    #6
  7. Thomas Heinz

    Guest

    Thomas Heinz <> wrote in message news:<ccjnal$5e55q$-saarland.de>...
    > ...
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables.


    It's not that g++ "likes" that. It is carved in standard
     
    , Jul 8, 2004
    #7
  8. [NT] Nameing of parameter lists (was Questionable compiler warning)

    "Gary Labowitz" <> wrote in message
    news:...
    > "Thomas Heinz" <> wrote in message
    > news:ccjnal$5e55q$-saarland.de...

    <snip>
    > > class T
    > > {
    > > int b, a;
    > > T(int a, int b) : a(a), b(b) {}
    > > };


    A side note (and New Topic):
    While the parameter list in a constructor can use the same identifiers as
    the class member names, it is probably a bad habit to get into since it will
    bite you if used for methods. I recommend using some convention to identify
    parameters as different from the class members, say
    T(int Ia, int Ib) : a(Ia), b(Ib) {}
    or
    T(int newA, int newB) a(newA) b(newB) {}
    etc.
    --
    Gary
     
    Gary Labowitz, Jul 8, 2004
    #8
  9. Thomas Heinz wrote:
    > Consider the following program.
    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(b) {}
    > };
    >
    > g++ -Wall -c test.cc produces the following warning.
    >
    > test.cc: In constructor `T::T(int, int)':
    > test.cc:3: Warnung: `T::a' will be initialized after
    > test.cc:3: Warnung: `int T::b'
    > test.cc:4: Warnung: when initialized here
    >
    >
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables.


    Yes. That's what the language standard requires it do do.

    > Does anyone know whether/why it is critical
    > for them to have the same order?


    It is required by the standard. As for being "critical"... I'd say you
    should ask yourself whether the initialization order is critical in your
    particular case. And if it is, you should either carefully keep the
    member declarations in proper order (which is not always possible) or
    move certain initializations from the initializer list to the
    constructor's body.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Jul 8, 2004
    #9
  10. Thomas Heinz

    Arijit Guest

    Thomas Heinz <> wrote in message news:<ccjnal$5e55q$-saarland.de>...
    > Hi
    >
    > Consider the following program.
    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(b) {}
    > };
    >
    > g++ -Wall -c test.cc produces the following warning.
    >
    > test.cc: In constructor `T::T(int, int)':
    > test.cc:3: Warnung: `T::a' will be initialized after
    > test.cc:3: Warnung: `int T::b'
    > test.cc:4: Warnung: when initialized here
    >
    >
    > Obviously, g++ likes the initialization order to be
    > the same as the declaration order of the corresponding
    > variables. Does anyone know whether/why it is critical
    > for them to have the same order?
    >
    > Thanks for your help.
    >
    >
    > Regards,
    >
    > Thomas



    The initialization order followed is the declaration order,
    and not the order used in the constructor. Otherwise, you could
    write two different constructors that initialize the variables
    in two different orders. This is usually not important and
    you can ignore this warning almost always. However, in special
    cases this can make a difference. g++ generates the warning in
    case you expect a to be initialized before b.

    -Arijit
     
    Arijit, Jul 8, 2004
    #10
  11. Thomas Heinz

    Thomas Heinz Guest

    Hi Gary

    You wrote:
    > ...
    > T(int a, int b) : a(a), b(a*3 + b) {}
    > ...
    > Can you see that this won't work because b will be initialized first, using
    > an uninitialized a? That's why the warning was issued.
    > Changing the order in the declaration would allow this initialization list
    > to work properly.


    class T
    {
    int b, a;
    T(int a, int b) : a(a), b(a*3 + b) {}
    };

    is equivalent to

    class T
    {
    int b, a;
    T(int _a, int _b) : b(_a*3 + _b), a(_a) {}
    };

    and not to

    class T
    {
    int b, a;
    T(int a, int b) : b(T::a*3 + T::b), a(T::a) {}
    };


    Hence, in your case b is initialized using the
    constructur parameter a and not the member a.


    Regards,

    Thomas
     
    Thomas Heinz, Jul 8, 2004
    #11
  12. Thomas Heinz

    Ali Cehreli Guest

    Re: [NT] Nameing of parameter lists (was Questionable compiler warning)

    On Thu, 08 Jul 2004 10:37:40 -0700, Gary Labowitz wrote:

    > "Gary Labowitz" <> wrote in message
    > news:...
    >> "Thomas Heinz" <> wrote in message
    >> news:ccjnal$5e55q$-saarland.de...

    > <snip>
    >> > class T
    >> > {
    >> > int b, a;
    >> > T(int a, int b) : a(a), b(b) {}
    >> > };

    >
    > A side note (and New Topic):
    > While the parameter list in a constructor can use the same identifiers
    > as the class member names, it is probably a bad habit to get into since
    > it will bite you if used for methods.


    Good advice!

    It is probably more surprising and risky in the constructor. Consider
    needing to move the initialization of a member into the body of the
    constructor in the future for some reason. This time, not the member,
    but the constructor argument would be assigned:

    struct S
    {
    int i;

    explicit S(int i)
    :
    i(1) // <-- initialize member
    {
    i = 2; // <-- assign to argument
    }
    };

    #include <iostream>

    int main()
    {
    S s(0);
    std::cout << s.i << '\n';
    }

    > I recommend using some convention
    > to identify parameters as different from the class members, say
    > T(int Ia, int Ib) : a(Ia), b(Ib) {}
    > or
    > T(int newA, int newB) a(newA) b(newB) {}
    > etc.


    One of the popular conventions is to append an underscore to the
    member name:

    class C
    {
    int value_;
    /* ... */
    };

    I find this kind of name decoration very helpful especially in the
    implementation files (.cpp, .cc, etc) when I am trying to figure out
    where an object is defined. The appended underscore makes me see right
    away that the object is a member.

    Otherwise, I would need to search back higher in the scopes to see
    where the object was introduced. Only after not finding it that way, I
    would realize that it might be a member.

    Ali
     
    Ali Cehreli, Jul 8, 2004
    #12
  13. "Thomas Heinz" <> wrote in message
    news:cckelr$ccu$06$-online.com...
    > Hi Gary
    >
    > You wrote:
    > > ...
    > > T(int a, int b) : a(a), b(a*3 + b) {}
    > > ...
    > > Can you see that this won't work because b will be initialized first,

    using
    > > an uninitialized a? That's why the warning was issued.
    > > Changing the order in the declaration would allow this initialization

    list
    > > to work properly.

    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : a(a), b(a*3 + b) {}
    > };
    >
    > is equivalent to
    >
    > class T
    > {
    > int b, a;
    > T(int _a, int _b) : b(_a*3 + _b), a(_a) {}
    > };
    >
    > and not to
    >
    > class T
    > {
    > int b, a;
    > T(int a, int b) : b(T::a*3 + T::b), a(T::a) {}
    > };


    Hey, right you are. Thanks. That's what I meant.
    --
    Gary
     
    Gary Labowitz, Jul 9, 2004
    #13
    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. Pete Becker
    Replies:
    0
    Views:
    1,407
    Pete Becker
    Feb 10, 2005
  2. Rouben Rostamian

    questionable cast

    Rouben Rostamian, Jan 18, 2004, in forum: C Programming
    Replies:
    6
    Views:
    368
    Barry Schwarz
    Jan 19, 2004
  3. Andrew
    Replies:
    2
    Views:
    398
    Pete Becker
    Oct 19, 2007
  4. Juha Nieminen
    Replies:
    11
    Views:
    634
    Triple-DES
    Jan 12, 2009
  5. Questionable advice

    , Sep 8, 2013, in forum: C++
    Replies:
    50
    Views:
    719
Loading...

Share This Page