[ub] launder and aliasing

Gabriel Dos Reis gdr at microsoft.com
Fri Feb 26 22:55:49 CET 2016


| I don't think that is the right interface for such functionality. No matter what you
| do with the pointer, if you create a situation where an int* and a float* can
| simultaneously exist and both can be used to load or store the same memory,
| you destroy TBAA.

+1.
See my comment about blowing off the entire planet.
Patrick, a few months ago, made a comment about how scary std::launder is -- he is right :-)

| Gaby had a paper that would guarantee that memcpy can be used to reinterpret
| the bytes of an object of one type as a value of another type; that would seem
| to fit the bill here. And you can use that to build higher-level operations, such as
| this:

I was meaning to update that paper for Jacksonville, because it has to go in C++17, but life happened.
This that paper is the consensus of SG12 (as we reviewed it in Kona), I will make sure it gets honorable mention in Jacksonville and we have a full wording in the post-Jacksonville mailing for consideration for C++17 in Oulu.

| 
|   template<typename T, typename U> T *change_object_type(U *p) {
|     static_assert(sizeof(T) == sizeof(U));
|     static_assert(is_trivially_copyable_v<T> && is_trivially_copyable_v<U>);
|     char buffer[sizeof(T)];
|     memcpy(buffer, p, sizeof(T));
|     p->~U();
|     T *result = new (p) T;
|     memcpy(result, buffer, sizeof(T));
|     return result;
|   }
| 
|   int foo(float f) {
|     int *i = change_object_type<int>(&f); // float is dead, long live the int!
|     return *i;
|   }
| 
| Your compiler ought to be able to be able to optimize that down to essentially
| nothing (maybe a round-trip through memory to convert a floating-point
| register to an integer register, or maybe just a mov from one register to
| another, depending on CPU architecture, ABI, etc.).

-- Gaby



More information about the ub mailing list