-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Small Buffer Optimization is a common and widespread container implementation strategy for containers that do not have as strong a guarantee for iterator invalidation as std::vector, such as std::string. With both vector and string being made constexpr, Small Buffer Optimization cannot be done legally at constexpr time due to the inability to invoke std::construct_at or std::destroy_at on memory that has automatic storage duration. That is, the wording does not seem to bless the following program as legal:
#include <memory> constexpr int foo () { int x = 0; std::destroy_at(&x); std::construct_at(&x, 2); return x; } constexpr int bar () { int x[2]{}; std::destroy_at(&x[0]); std::construct_at(&x[0], 3); return x[0]; } int main () { static_assert(foo() == 2); static_assert(bar() == 3); }
This presents problems for a future wherein someone wishes to work with SBO containers, and may present a serious problem for the future work with getting constexpr-capable containers to escape compile-time and serialize into something that can be used at runtime.
Proposed change:
Change [expr.const/5.1-2] to read as follows:
— for a call to std::construct_at or std::ranges::construct_at, the first argument, of type T*, does not point to either storage allocated with std::allocator<T> or an automatic storage duration variable of type T, or the evaluation of the underlying constructor call is not a core constant expression, or
— for a call to std::destroy_at or std::ranges::destroy_at, the first argument, of type T*, does not point to either storage allocated with std::allocator<T> or an automatic storage duration variable of type T, or the evaluation of the underlying destructor call is not a core constant expression.