If two objects are declared in a single line, in which order are they constructed?
Asked Answered
T

5

62

Let's say a class has been defined as

class A {
//.....
};

and now I am creating two objects as

A a,b;

In what order are a and b created? Is it defined by the standard?

Thirtytwomo answered 22/2, 2016 at 18:26 Comment(12)
The comma in a declaration is not the comma operator, it's merely a separator.Bannon
Possible duplicate of How does the Comma Operator workRanita
In this case it is not the comma operator.Roop
@Ranita No. We are not using the comma operator hereRoop
You could test this.Akers
@Roop that question contains all answers. Look at comment 4 by CygnusX1. It explains when comma is operator and when it is not, and how it behaves.Ranita
@Ranita But it does not answer in which order are the objects initialized.Roop
@Akers ..I can test it but I wouldn't know if the result is implementation dependent or notThirtytwomo
@pasha, You are right. There could be a difference between the implementation and the standard. Then again, getting an answer on StackOverflow could leave you wondering if there is a difference between the answer and the standard. ;-)Akers
@Akers Not if the answer quotes the standard. ;)Roop
@Roop Excellent!Akers
IMO if you actually depend on a particular order of construction in any way, you should make that clear by setting the declarations apart (regardless of what order the Standard guarantees for a single-line declaration).Belsen
S
78

From 8 Declarators [dcl.decl] 3:

Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.

It goes on to say

A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is T D1, D2, ... Dn; is usually equivalent to T D1; T D2; ... T Dn; where T is a decl-specifier-seq and each Di is an init-declarator. An exception occurs when a name introduced by one of the declarators hides a type name used by the decl-specifiers, so that when the same decl-specifiers are used in a subsequent declaration, they do not have the same meaning.

You can say that they are constructed from left to right.

Socialization answered 22/2, 2016 at 18:35 Comment(11)
Beat me by 45 seconds :-)Deweese
@erip..thanks for the answer. Can I do T D1,D2=D1; or not?Thirtytwomo
@Thirtytwomo T D1,D2=D1; becomes T D1; T D2=D1; by the rules so yes.Roop
Well, it says 'usually'.Unpolite
Yep. It will call default ctor on D1 and copy assignment on D2 with D1.Socialization
@Socialization It would call the copy constructor for D2. Not the copy assignment operator.Evetta
@Brian Indeed. Careless comment on my behalf. :)Socialization
Could someone formulate an example for what the exception to "usually" means?Meeting
@HagenvonEitzen: Main example is when a variable has the same name as the type. S S,T; works; S S; S T; is an error. Newer example is auto x=1; auto y=2.0; works; auto x=1,y=2.0; is an error. Those are the only examples the footnote provides. So "usually" is, if anything, a bit of an understatement.Deweese
@Deweese Indeed. And frankly I don't even like the idea of S S, T;Socialization
@erip: Yes, no sane person would let something like that through code review, never mind writing it themselves.Deweese
D
52

C++ spec chapter 8 [dcl.decl], says:

Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself. (100)

Footnote (100) goes on to say:

(100) A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is

T D1, D2, ... Dn;

is usually equivalent to

 T D1; T D2; ... T Dn;

...and then names some exceptions, none of which apply in such simple cases.

So the answer to your question is that the objects are constructed in the order you list them. And no, it is not a comma operator.

Deweese answered 22/2, 2016 at 18:36 Comment(4)
How do you understand 'usually' in this context?Unpolite
@Unpolite By reading the exceptions in which case 'usually' becomes 'no' then taking the complement for the affirmative. :)Socialization
@erip, quite a process :)Unpolite
@Unpolite As I'm sure you know, that's the name of the game when writing C++. ;DSocialization
A
11

The order is the written order, from left to right. Also, it's not the comma operator, but simply a list of declarators. When a user-defined comma operator is used, order is in fact unspecified.

See comma operator and declarators.

Achelous answered 22/2, 2016 at 18:31 Comment(0)
C
8

a will be created first and then b.

Commas in this case will be used as separators and not as operators.

For example from wikipedia :

    /**
      *  Commas act as separators in this line, not as an operator.
      *  Results: a=1, b=2, c=3, i=0
      */
     int a=1, b=2, c=3, i=0;
Cf answered 22/2, 2016 at 18:30 Comment(0)
H
6

Standards:

Declarators [dcl.decl]:
Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.

Example:

class A {
public:
    A(std::string const &s): name(s) 
    { 
        std::cout << "I am " << name << '\n'; 
    }
    std::string name;
};

auto main() -> int
{
    A a("a"), b("b");
}

Output:

I am a
I am b
Hazaki answered 22/2, 2016 at 22:3 Comment(1)
This code isn't really a proof that this is true. The standard quote is.Socialization

© 2022 - 2024 — McMap. All rights reserved.