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
implement safer align_ function #141
Conversation
1c19187
to
d7b257b
Compare
This code needs an entire overhaul, so I don't think it's really worth refactoring to make it nicer. It also seems like fundamentally unsafe code to start with ( Ignoring the pre-existing problems with this code, introducing a new template with the same name as an existing one ( That said, the PR looks otherwise correct. |
For what it's worth, Clang has a |
Exactly. Making these templates |
Oh if you're happy with SFINAE and C++11 then how about: template<typename T>
static inline
std::enable_if_t<std::is_integral<T>::value>
align_(size_t __align, T __int) noexcept
{
return (__int - 1u + __align) & ~(__align - 1);
}
template<typename T>
static inline
std::enable_if_t<std::is_pointer<T>::value>
align_(size_t __align, T __ptr) noexcept
{
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
const auto __aligned = align_(__align, __intptr);
return reinterpret_cast<T>(__aligned);
} |
I didn't say I'm happy with SFINAE, just that it resolves this concern :-). I think SFINAE here is overkill, and the issue here is easily fixed without it. |
Well, personally I think having two different names for basically the same thing is more confusing and less elegant, but if that's what you'd prefer then sure. |
It is more confusing and less elegant to have two implementations. Either way, you have two implementations. SFINAE versus two different names might be the right call in better-designed code. If you think it's how you want to do it, then go for it! Still, it's an internal API call, and hopefully one that will be removed soon that a larger rewrite is in order, so don't worry too much either way. |
implemented split Thanks for the discussion. For some background on why I'm trying to refactor this tiny bit of code: I'm trying to build ROS2 on a system which, amongst other things, has very specific rules for pointer provenance. This particular piece of code was problematic and we tried to find a generic solution that maintainers might be happy to merge upstream, rather than just holding on to our own fork with specific work-arounds. |
avoids unnecessary casts to pointer and pointer manipulation by reference
Thanks for the background! Do note that there may be some issues with pointer alignment today. The deserialization code can already access doubles and uint64s through unaligned pointers today (which is UB, though I haven't seen it be an actual problem yet). If your system is picky about pointers, it might be picky about that too. |
It's only picky about unaligned loads/stores of pointers themselves. Normal integers/floats adhere to the base architecture's restrictions (there are version based on MIPS, RISC-V and AArch64 which all differ there, and some make it implementation-defined). |
I'm sorry it took so long. I assumed @eboasson would merge this. LGETM! |
:-p I don't know what I'm doing and I am scared to break everything |
No worries. Thanks very much for considering and working with us. |
avoids unnecessary casts to pointer and pointer manipulation by reference
avoids unnecessary casts to pointer and pointer manipulation by reference
Splits the
align_
function and overloads it avoids an unnecessary cast fromsize_t
tovoid *
.Avoids passing the casted pointer by reference. In the existing
align_
function, the pointer argument is both manipulated via reference and returned, which is both confusing and potentially dangerous, since it's behaviour is not clear from the function prototype.