hi I have static std::map with some values and static iterator to default element like this and initialize both at once:
in .h file
class foo
{
static std::map<std::string, int> sqlenumToInt;
static std::map<std::string, int> initEnumToInt();
static std::map<std::string, int>::iterator defaultIt;
};
in .c file
std::map<std::string, int> foo::sqlenumToInt = initEnumToInt();
std::map<std::string, int> foo::defaultIt = std::map<std::string, int>::iterator();
std::map<std::string, int> foo::initEnumToInt();
{
std::map<std::string, int> test;
defaultIt = test.insert(std::make_pair("a", 0)).first
test["b"] = 2;
test["c"] = 3;
test["d"] = 4;
return test;
}
What will be default order of initialization of static variables. Will be defaultIt only std::map::iterator() or iterator to first element of sqlenumToInt ??
Within a translation unit, initialization order of static variables is well defined; static variables are initialized in order of definition. So initEnumToInt
runs before foo::defaultIt
is initialized. In your code, this will result in undefined behaviour, since at the point initEnumToInt
runs, foo::defaultIt
is in an uninitialized (but zero-initialized) state; you are then calling operator=
on a zero-initialized object, and later calling the constructor that expects a zero- or un-initialized object.
The way you've written it, you're accessing an uninitialized element, since the initalizer for sqlenumToInt
is evaluated first; this may be undefined behaviour (depending on the details of the iterator type).
If you want the front of the map, say defaultIt = sqlenumToInt.begin()
in the initializer and remove it from initEnumToInt()
.
(Moreover, even the iterator that you obtained in your function would be meaningless, since it becomes invalid as soon as the local map object is destroyed.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With