isocpp / isocpp/CppCoreGuidelines
C.183 recommend bit_cast for type punning
@cubbimew is already working on this.
Since Jan 26, 2023.
- Dominant language
- CSS
- Stars
- 45.3k
- Forks
- 5.6k
- PR merge metrics
- No merged PRs in 30d
Description
C.183 says that unions shouldn't be used for type punning but IMHO the guidance it provides on what to use instead leaves room for improvement. It mentions reinterpret_cast for casting to char*, unsigned char*, or std::byte. AFAIK we need to keep the following things in mind when punning types:
reinterpret_cast<bar>(foo)is UB ifbarhas stricter alignment requirements than the type offoo.reinterpret_casting a pointer to astd::bytebuffer togadget*and then using this pointer to call member functions/access member variables is UB since no instance ofgadgethas been instantiated (object lifetime).- In general
reinterpret_castmight lead to UB due to aliasing (example demonstrating this).
I guess it would be better to suggest a way which is safe with respect to all three points. In particular I would like to suggest replacing the reinterpret_cast paragraph by something along the following lines:
Use std::bit_cast (introduced with C++20) for type punning. If your standard library doesn't support std::bit_cast, yet, use std::memcpy instead. This is preferred over using union or reinterpret_cast since bitcast and memcpy reliably prevent undefined behavior due to violated alignment/aliasing rules. In practice modern compilers are often able to eliminate the copy.
Example:
// Assume sizeof(int) == sizeof(float) for these examples
void if_you_must_pun(float& x)
{
auto i = std::bit_cast<int>(x);
cout << i << '\n';
}
void if_you_must_pun_pre_cpp20(float& x)
{
int i;
memcpy(&i, &x, sizeof(x));
cout << i << '\n';
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.