Question

Previously asked questions (1 and 2) on SO seem to suggest that applying std::move on elements of a std::initializer_list may lead to UB. In fact, std::initializer_list iterators prevent effective move because they refer to const elements. The reason is that compilers may use static read-only memory for storing the underlying array of an initializer_list.

I think this view is too limiting and I wanna know if experts out here agree. IMO, the following code cannot possibly use the read-only store.

void attempt_move(std::initializer_list<std::string> list) {
  // must use const std::string &. Can't move.
}
int main(int argc, char *argv[])
{
  if(argc >= 4)  
    attempt_move({ argv[1], argv[2], argv[3] }); 
}

The underlying std::string array cannot possibly live in a read-only store because, AFAIK, read-only store must be initialized before main and the argv parameters are not known at that time. In fact, the C++11 standard says: "[ Note: The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. —end note ]". Seems like this is one case where the "explicit array with the same initializer" cannot be allocated read-only. So it probably has automatic storage.

If that's true, seems like there are lost opportunities to move the string objects due to const iterators of std::initializer_list. Is there a workaround?

Was it helpful?

Solution

You can const_cast away qualification if the underlying object isn't const-qualified, but only the reference is.

But const qualification isn't necessarily the same thing as being stored statically in physical ROM. In most cases, the compiler simply believes it's safe that the object won't be modified by anyone.

Yes, it's undefined behavior. And this is considered a serious shortcoming of initializer_list. Hopefully it will be fixed for C++17.

Yes, you'll probably get away with it if moving is the only thing that ever happens to those elements, which in fact covers almost all the safe use-cases of initializer_list under the sun.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top