2

I want to know the reason why constructors are called in the order in which objects are declared.

I read this question but i am not getting the reason specified there as a comment.

Stated reason is:

The reason for which they are constructed in the member declaration order and not in the order in the constructor is that one may have several constructors, but there is only one destructor. And the destructor destroy the members in the reverse order of construction.

Can someone please explain this?

Community
  • 1
  • 1
  • 1
    How would the compiler know what order the members were initialized in if that order could change depending on which constructor was called? – Galik May 28 '15 at 07:03

2 Answers2

7
  1. sub-object destructors should always be called in reverse order compared to sub-object constructors (otherwise way too many things will fall apart)

  2. There can be multiple constructors of the object, each with it's own order of sub-objects in the list

  3. If we call sub-object constructors in the order which is specific to each object constructor, we won't be able to get one single order for sub-object destructors.

  4. Hence, the decision to have in the order of declaration, which doesn't depend on the order of sub-objects in different object constructors.

No-Bugs Hare
  • 1,557
  • 14
  • 15
  • 1
    In point 3, "we won't be able to get one single order for sub-object destructors" is, uhm, incomplete, in that that consequences are not fleshed out. But it would likely have a run time cost. I can't think of any cost-free way to do it. – Cheers and hth. - Alf May 28 '15 at 07:37
  • @Cheersandhth.-Alf: Right, you can implement it via adding a "which constructor was used to construct", or "order of constructors" implicit field to each object. It won't be C++ anymore though. – No-Bugs Hare May 28 '15 at 07:59
  • Re "it won't be C++ anymore", that doesn't make sense to me, sorry. Any different rules will technically yield a different language, true. But in that sense the language changes at every update of the standard. Hey, C++03 isn't C++ any more, what with this newfangled value initialization. Oh, C++11 isn't C++ anymore. Hey, C++14 isn't C++ anymore. It is a valid point of view, but I do not understand what it's about. Sorry. – Cheers and hth. - Alf May 28 '15 at 18:17
  • @Cheersandhth.-Alf C++ has a principle of "zero cost abstraction" - which effectively rules out that runtime cost you mention. Therefore, if doing so, "it will be not C++ anymore" (not just "not C++11 anymore", but "no C++ at all"). Not that it really matters - but what I wrote _is_ the reason why it wasn't done any other way. If in doubt - you can always ask Bjarne... – No-Bugs Hare Aug 13 '23 at 16:45
  • "you can always ask Bjarne", well I don't think I have his e-mail address anymore, and he's long gone from the Usenet groups; asking Bjarne was just in the old days, and he endeavored to answer any question from anyone. FWIW I think the principle of least surprise, where the order of destructor calls is known at compile time, is the more important one here. The zero cost principle is one that's been overruled several times. – Cheers and hth. - Alf Aug 24 '23 at 17:51
1

A basic language design principle in C++ is that "you don't pay for what you don't use".

It's not perfectly applied, e.g. one does pay for threads, and for exceptions, even if they're not used. Which is one reason why C still has a good niche. But in general, if a language feature would impose some cost even where it's not used, then it's not there.

Ensuring that destruction order is opposite of construction order is essential for correctness. But doing that for arbitrary construction orders, which might be defined in other translation units, would incur the overhead of a dynamically established destruction order. And that cost would very rarely buy any advantage (e.g., I have never needed different initialization orders for different constructors, and I have used C++ since the 1990's).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331