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.

链接地址: http://www.djcxy.com/p/64048.html

上一篇: 删除多个类(jQuery)

下一篇: 有没有办法避免严格的锯齿警告?