I see many places in public repositories, where the first and last iterators of std::vector/std::string/std::string_view are converted into pointers using the combination of &* operators. In particular, it is frequently used for calling std::from_chars, e.g.
auto const parse_int = [](std::string_view sv, int base = 10) -> int {
int value;
auto result = std::from_chars(&*sv.begin(), &*sv.end(), value, base);
...
Is it actually safe and not undefined behavior to dereference end() (which points on the element following the last element in the container/view) with * before converting it back to the pointer with &?
I tried to evaluate a similar code with &* in a constant expression, where undefined behavior must be detected by the compiler:
static_assert( [] {
const char s[3] = { 'e', 'n', 'd' };
[[maybe_unused]] auto * a = &*(s+3); // ok?
[[maybe_unused]] auto & b = *(s+3); // ok?
return true;
}() );
But actually all compilers are fine with it, and do not complain, online demo.
No, its undefined behaviour, MSVC's debug iterators crash with the code: https://godbolt.org/z/K3a8YEYsr
This is a known deficiency with std::from_chars, see: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2007r0.html
The legal way to do it is with:
std::from_chars(sv.data(), sv.data() + sv.length(), value, base);