Is there a way to avoid the strict anti-aliasing warning?
I am using a library (ENet) that uses callbacks. In these callback functions, it passes a structure that contains void * for user data for your own use. I would like to use this variable, but not as a pointer. I don't want to allocate memory so that I can point to it, I would rather use void * space directly to store size_t.
But as expected, when I pass the void * variable to the size_t variable, I get a strict alias. And the callback structure does not provide a connection to access it like anything other than void *.
I know I can turn off this warning completely, but I'd rather just turn it off for this particular case. Is there a way to write a collection of this type that allows the compiler to know that this is intentional in order to avoid the warning?
Edit:
Here is an example of what I am trying to do. Since I need to be able to edit the user's value, I cast it to size_t and also try to get a reference to it:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
This works but gives a warning.
source to share
But as expected, when I dereference the void * variable with the size_t variable, I get a line alias warning.
If you only want to use a void *
simple integer to carry only, you don't want to play it out, you want to pass it to the appropriate integral type ( intptr_t
is your best bet as the Standard makes sure it can survive the round trip 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 styles they all will reinterpret_cast
)
Also, you are probably doing something weird in your code because void *
(for example, char *
and unsigned char *
) is not subject to the strict rule of aliases (they can be like any other pointer).
Update
Here is an example of what I am trying to do. Since I need to be able to edit the user's value, I cast it to size_t and also try to get a reference to it:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
This works but gives a warning.
No, even assuming that size_t
both void *
have the same size and alignment requirements (which are not guaranteed), this cannot be done portable; aliasing a void *&
with a is size_t &
not allowed (it is also especially tricky because it is hidden in the link).
If you really need to do this, you need to negotiate with your compiler; For example, in gcc, you can only compile the file where you have this thing with -fno-strict-aliasing
, which, instead of just disabling the warning (= hides a potential problem under the rug) disables the compiler's strong alias assumptions, so that the generated code works correctly even if pointers / unrelated type references point to the same material.
source to share