Why c++ initializer list order does not matter (or does it ? )

When using const members in your class you have to construct them in a initializer list. But in which order should you construct them ? I created a example where the order actually matters — we need Cylinders first before we can construct a Car’s engine. But the following code holds a nasty bug. Can you spot it ?

struct Engine{
std::vector<std::string> cylinders;
};
class Car{
public:
const Engine mEngine;
const std::vector<std::string> mCylinders;
Car(std::vector<std::string> cylinders):
mCylinders(cylinders),mEngine(mCylinders){}
};

Here is an basic main() function that constructs a Car and then prints all cylinders in the car’s engine:

int main()
{
const Car car({"Cyl 1","Cyl 2"});
std::cout <<"Engine has ";
for(const auto s:car.mEngine.cylinders){
std::cout<<s<<" ";
}
std::cout<<" cylinders"<<std::endl;
return 0;
}

But this won’t print any cylinders. Try it out yourself: (either of both)

https://onlinegdb.com/SJyStXHoI

https://wandbox.org/permlink/5HNe8yz6ck6WzaM9

So whats the issue ? When looking at the initializer list, the Car’s cylinders myCylindersare created first, then used in the constructor of mEngine.But unfortunately, this order does not matter. What matters is the order in which the members were declared inside the Car class. There mEngine comes before mCylinders , and as a result mEgine does not contain any cylinders.
How do you fix this ? Just swap the order in which mEngine and mCylinders are declared inside Car , and remember that the order inside your initalizer list does not matter. If you are using gcc as a compiler, it will warn you about this mistake, but llvm will not.