Is there a way to avoid the strict aliasing warning?
I'm using a library (ENet), which uses callbacks. In those callback functions, it passes a struct which contains a void* for user data, for your own use. I'd like to use that variable, but not as a pointer. I don't want to allocate memory just so I can point to it, I'd rather use the space of the void* directly to store a size_t.
But, as expected, when I cast the void* variable to a size_t variable, I get a strict alias warning. And the callback's struct doesn't provide a union to access it as something other than a void*.
I know I can disable that warning completely, but I'd rather just silence it for this particular case. Is there a way to write a cast of this sort that lets the compiler know it is intentional, to avoid the warning?
Edit:
Here is an example of what I'm trying to do. Since I need to be able to edit the user value, I'm casting it to size_t while also trying to grab a reference to it:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
This works, but gives the warning.
But, as expected, when I dereference the void* variable to a size_t variable, I get a strict alias warning.
If you want to use the void *
itself just to transport a plain integer, you don't want to dereference it, you want to cast it to an appropriate integral type ( intptr_t
is your best bet, as the standard guarantees that it can survive to a roundtrip through void *
).
intptr_t magic=42;
register_callback(&myfunc, (void *)magic);
// ...
void myfunc(void *context)
{
intptr_t magic=(intptr_t)context;
// ...
}
(if you like C++-style casts, those would all be reinterpret_cast
)
Besides, you are probably doing something weird in your code, because void *
(like char *
and unsigned char *
) is not subjected to the strict aliasing rule (they can alias any other pointer).
Update
Here is an example of what I'm trying to do. Since I need to be able to edit the user value, I'm casting it to size_t while also trying to grab a reference to it:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
This works, but gives the warning.
Nope, even assuming that size_t
and void *
had the same size and alignment requirements (which is not guaranteed), this cannot be done portably; aliasing a void *&
with a size_t &
is not allowed (also, this is particularly devious because it's hidden in a reference).
If you really need to do this, you have to come to terms with your compiler; in gcc, for example, you could compile just the file where you have this thing with -fno-strict-aliasing
, which, instead of simply disabling the warning (=hiding the potential problem under the carpet), disables the compiler assumptions about strict aliasing, so that the generated code works correctly even if pointers/references to unrelated types point to the same stuff.
上一篇: 删除多个类(jQuery)
下一篇: 有没有办法避免严格的锯齿警告?