简体   繁体   中英

C Casting from pointer to uint32_t to a pointer to a union containing uint32_t

I'd like to know if casting a pointer to uint32_t to a pointer of a union containing a uint32_t will lead to defined behavior in C, ie

typedef union
{
    uint8_t u8[4];
    uint32_t u32;
} T32;

void change_value(T32 *t32)
{
    t32->u32 = 5678;
}

int main()
{
    uint32_t value = 1234;

    change_value((T32 *)&value); // value is 5678 afterwards

    return EXIT_SUCCESS;
}

Is this valid C? Many thanks in advance.

The general answer to your question is, no, this is in general not defined. If the union contains a field that has larger alignment than uint32_t such a union must have the largest alignment and accessing that pointer would then lead to UB. This could eg happen if you replace uint8_t in your example by double .

In your particular case, though, the behavior is well defined. uint8_t , if it exists, is most likely nothing other than unsigned char and all character types always have the least alignment requirement.

Edit: As R.. mentions in his comments there are other issues with your approach. First, theoretically, uint8_t could be different from unsigned char if there is an unsigned "extended integer type" of that width. This is very unlikely, I never heard of such an architecture. Second, your approach is subject to aliasing issues, so you should be extremely careful.

At the risk of incurring downvotes... Conceptually, there is nothing wrong with what you are trying to do. That is, define a piece of storage that can be viewed as four bytes an a 32 bit integer, and then reference and modify that storage using a pointer.

However, I would ask why you would want to write code where its intent is obscured. What you are really doing is forcing the next programmer who reads your code to think for minutes and maybe even try a little test program. Thus, this programming style is "expensive".

You could have just as easily defined, value as:

 T32  value;
 // etc.
 change_value(&value); 

and then avoid the cast and subsequent angst.

由于保证所有的工会成员都从相同的内存地址开始,因此编写的程序不会导致未定义的行为。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM