Current Solidity docs provide the answer in this paragraph: https://docs.soliditylang.org/en/v0.8.13/contracts.html#multiple-inheritance-and-linearization
Basically: Solidity guarantees that all the base classes' constructors will be called before a derived class constructor. And it is not possible tothe derived class constructor cannot change the order in which base classes constructors are called by Solidity.
But this is a bit complicated as Solidity has to deal with multiple inheritance. AsAs explained in the docs, the inheritance graph for the derived class is linearized using C3 linearization, which yields an ordered list of classes where each derived class appears after all its base classes. The constructors are called in the order of the list. When you have more than one base class, the order that they appear in the list will be influenced by the order in which they are listed in the inheritance list (ie after the is
).
Quoting from the documentation:
One area where inheritance linearization is especially important and perhaps not as clear is when there are multiple constructors in the inheritance hierarchy. The constructors will always be executed in the linearized order, regardless of the order in which their arguments are provided in the inheriting contract’s constructor. For example:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; contract Base1 { constructor() {} } contract Base2 { constructor() {} } // Constructors are executed in the following order: // 1 - Base1 // 2 - Base2 // 3 - Derived1 contract Derived1 is Base1, Base2 { constructor() Base1() Base2() {} } // Constructors are executed in the following order: // 1 - Base2 // 2 - Base1 // 3 - Derived2 contract Derived2 is Base2, Base1 { constructor() Base2() Base1() {} } // Constructors are still executed in the following order: // 1 - Base2 // 2 - Base1 // 3 - Derived3 contract Derived3 is Base2, Base1 { constructor() Base1() Base2() {} }