C++ Logo

std-proposals

Advanced search

Re: [std-proposals] TBAA and extended floating-point types

From: Paul Caprioli <paul_at_[hidden]>
Date: Sat, 9 Aug 2025 08:03:30 +0000
>> Supposing that double is IEEE-754 binary64 and ptr has type double*, >> is it safe to reinterpret_cast<std::float64_t*>(ptr) and then use it to read or modify memory >> that is an array of doubles? >> I could not find that this is allowed, so I would like to float the idea for such a proposal. > Unless otherwise stated, this violates strict aliasing and it's not > allowed. Even if the compiler manual says that you can do it, it's > undefined behavior and wouldn't work in constant expressions. > We arguably have the right tools to deal with this situation already. > For scalars that you want to pass between libraries, you can > std::bit_cast<double> or std::bit_cast<std::float64_t> at the library > bounds. For blocks of mutable data, you can use > std::start_lifetime_as_array to reinterpret the elements without > accessing storage. For scalars, one can rely on implicit conversion, but I'm struggling with pointers. Please correct me if I'm wrong, but I think I need a way to re-start the lifetime after memory is modified. For example, in the following, it looks like the compiler can skip the daxpy() call in main() because no doubles are written. So, the program can print 3.0 instead of the expected 5.0. Also, by starting a new lifetime in the existing storage, did I end the old lifetimes of the doubles in both x and y? Do I need to memcpy() both x.data() and y.data() somewhere before the daxpy(), and after it use start_lifetime_as_array<double>, and then y.assign()? #include <iostream> #include <memory> #include <stdfloat> #include <vector> void daxpy(std::size_t n, const std::float64_t alpha, const std::float64_t* x, std::float64_t* y) { for (std::size_t i = 0; i < n; ++i) y[i] += alpha * x[i]; } int main() { std::size_t n = 40; double alpha = 2.0; std::vector<double> x(n, 1.0); std::vector<double> y(n, 3.0); daxpy(n, alpha, std::start_lifetime_as_array<std::float64_t>(x.data(), n), std::start_lifetime_as_array<std::float64_t>(y.data(), n)); std::cout << y[17] << '\n'; // UB? }

Received on 2025-08-09 08:03:34