Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructing initializer_list by enumerating values contains random values

While thinking about solution for question std::initializer list from already existing std::array without enumerating each element, I developed similar mechanism as bolov did, but not constructing the object, but rather only initializer list. I was surprised that my solution did not work and I couldn't figure out why.

#include <initializer_list>
#include <iostream>
#include <array>

template<typename T, std::size_t N, std::size_t... Is>
std::initializer_list<T> array_to_init_list_helper(std::array<T, N> arr, std::index_sequence<Is...>)
{
    return {arr[Is]...};
}

template<typename T, std::size_t N>
std::initializer_list<T> array_to_init_list(std::array<T, N> arr)
{
    return array_to_init_list_helper(arr, std::make_index_sequence<N>{});
}

int main()
{
    std::array<int, 5> arr{1, 2, 3, 4, 5};
    auto init_list = array_to_init_list(arr);
    for (auto val : init_list)
        std::cout << val << " ";
}

I am getting random values, while I would expect to get values of arr.

like image 222
Zereges Avatar asked Aug 07 '17 13:08

Zereges


1 Answers

Going through the assembly here (clang 4.0.0) and/or here (GCC 7.1), it is clear that the std::initializer_list is using a dangling pointer, which (as we all know) produces seemingly random output.

EDIT

This result is of course in line with the comment made by Igor Tandetnik, quoting cppreference.com:

The underlying array is a temporary array of type const T[N], in which each element is copy-initialized (except that narrowing conversions are invalid) from the corresponding element of the original initializer list. The lifetime of the underlying array is the same as any other temporary object, except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary (with the same exceptions, such as for initializing a non-static class member). The underlying array may be allocated in read-only memory.

like image 84
Jonas Avatar answered Sep 28 '22 05:09

Jonas