Date
2024-05-14.11:16:01
Message id
14142

Content

As a result of the new constructor added by P1391, this stopped working in C++20:


void fun(string_view);
void fun(vector<string_view>);
fun({"a", "b"});

Previously the first `fun` wasn't viable, so it constructed a vector<string_view> of two elements using its initializer-list constructor and then called the second `fun`. Now `{"a", "b"}` could also be a call to the new `string_view(Iter, Iter)`, so it's ambiguous and fails to compile.

The following case is arguably worse as it doesn't become ill-formed in C++20, it still compiles but now has undefined behaviour:


fun({{"a", "b"}});

Previously the first `fun` wasn't viable, so this constructed a vector<string_view> of two elements (via somewhat bizarre syntax, but using the same initializer-list constructor as above). Now it constructs a `vector` from an `initializer_list` with one element, where that element is constructed from the two `const char*` using `string_view(Iter, Iter)`. But those two pointers are unrelated and do not form a valid range, so this violates the constructor's precondition and has undefined behaviour. If you're lucky it crashes at runtime when trying to reach `"b"` from `"a"`, but it could also form a `string_view` that reads arbitrary secrets from the memory between the two pointers.