-
-
Notifications
You must be signed in to change notification settings - Fork 657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bit_cast
, and use it for _beginthreadex
calls
#3380
Conversation
Added a rudimentary `bit_cast` implementation for C++14/C++17, mimicking C++20 `std::bit_cast`.
A C-style cast of a `uintptr_t` (the return type of `_beginthreadex`) to a pointer type (`void *` or `HANDLE`) may easily lead to undefined behavior. This is avoided hereby, by using `bit_cast` instead.
@dzenanz I'm sorry, my claim that the
In this particular case, the I still think that in this particular case, In other cases, bit_cast does actually prevent undefined behavior, for example (https://godbolt.org/z/xearxvxM6):
|
For the record, this pull request + discussion appears related to issue isocpp/CppCoreGuidelines#1517 "Favor bit_cast over reinterpret_cast". |
@Leengit Could you possibly have a look at this issue as well? It seems that I was too eager to start using bit_cast, rather than reinterpret_cast! You may find the discussion at issue isocpp/CppCoreGuidelines#1517 "Favor bit_cast over reinterpret_cast" interesting. 😄 Jason Turner has two short video's on this topic, however, they don't seem to apply specifically to the So I'm now considering to replace the |
This is a new one for me and I haven't followed all your links, so I may end up wishing to eat my words in the next few hours or minutes but ... I am thinking that I would continue to use double * pDouble = nullptr;
// this next line is good enough because it is to char* (assuming sizeof(char)==1) or void*
char * pChar = reinterpret_cast<char *>(pDouble);
float f = 1.0f;
unsigned int i1 = std::bit_cast<unsigned int>(f); // yes
unsigned int i2 = *reinterpret_cast<unsigned int *>(&f); // now deprecated And if they are not trivially copyable then I don't know. |
It appears that commit 548b45f ("BUG: Replace C-style casts from `_beginthreadex` with `bit_cast<HANDLE>`", from pull request InsightSoftwareConsortium#3380) was wrong: `bit_cast<HANDLE>` might do a different conversion than the corresponding C-style cast, `(HANDLE)`. The C-style cast `(HANDLE)` behaves exactly like `reinterpret_cast<HANDLE>`, by definition. `reinterpret_cast<HANDLE>` does an implementation-defined conversion, as was explained by Jonathan Wakely at isocpp/CppCoreGuidelines#1517 (comment) (issue "Favor bit_cast over reinterpret_cast"). Fixed by replacing all `bit_cast<HANDLE>` calls with `reinterpret_cast<HANDLE>`.
It appears that commit 548b45f ("BUG: Replace C-style casts from `_beginthreadex` with `bit_cast<HANDLE>`", from pull request #3380) was wrong: `bit_cast<HANDLE>` might do a different conversion than the corresponding C-style cast, `(HANDLE)`. The C-style cast `(HANDLE)` behaves exactly like `reinterpret_cast<HANDLE>`, by definition. `reinterpret_cast<HANDLE>` does an implementation-defined conversion, as was explained by Jonathan Wakely at isocpp/CppCoreGuidelines#1517 (comment) (issue "Favor bit_cast over reinterpret_cast"). Fixed by replacing all `bit_cast<HANDLE>` calls with `reinterpret_cast<HANDLE>`.
bit_cast
helps to avoid undefined behavior when doing a bitwise cast.