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.

+3


source to share


1 answer


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.

+4


source







All Articles