void f() { constexpr int arr[] {1, 2, 3}; constexpr auto p = arr;}On 2015–11–03, at 6:04 AM, Columbo <r....@gmx.net> wrote:Is it possible to let local variables declared with constexpr have static storage duration? Since every constexpr variables's initializer can neither depend upon parameter values nor dynamically initialized (or modifiable) global state, they may as well have static storage duration with static initialization AFAICS.
Would that introduce any problems or have significant impacts?
Note that it would allow reasonable things that are currently disallowed, e.g.void f() {constexpr int arr[] {1, 2, 3};constexpr auto p = arr;}
The scheme uses less space while a function is recursing (it has at least two active stack frames), but potentially more space when it’s not executing. It may also reduce cache locality.
On the other hand, this is an area where some flexibility might be found. Already, sequence elements in std::initializer_list arrays are de-facto not guaranteed uniqueness.
Note that it would allow reasonable things that are currently disallowed, e.g.void f() {constexpr int arr[] {1, 2, 3};constexpr auto p = arr;}This works on GCC:constexpr std::initializer_list< int > il = { 1, 2, 3 };constexpr int const * p = il.begin();Clang rejects this, I guess because the initializer_list stores a pointer to the first element of the array and not a pointer to the entire array object, and because it validates the “permitted result of a constant expression” rule before applying the static storage optimization. I think that both are conforming, or at least, GCC is being reasonable :P.
The array held is temporary, thus not having static storage duration. Hence the "permitted result" rule is guaranteed to apply, AFAICS.
On 2015–11–03, at 5:07 PM, Columbo <r....@gmx.net> wrote:On Tuesday, November 3, 2015 at 3:52:57 AM UTC, David Krauss wrote:The scheme uses less space while a function is recursing (it has at least two active stack frames), but potentially more space when it’s not executing. It may also reduce cache locality.Do implementations not elide code and static local variables for functions that are never called? As a link-time optimization?
On the other hand, this is an area where some flexibility might be found. Already, sequence elements in std::initializer_list arrays are de-facto not guaranteed uniqueness.How is that? All these sequence elements are copied into a const array, and [intro.object]/6 guarantees that the elements have distinct addresses. If some of them were overlapping, that would not give the desired behavior for iteration.