C 一行两次浇铸

C 一行两次浇铸,c,casting,C,Casting,在一个项目中,我看到了下面的一行,我不明白为什么要投两次 *((MY_STRUCT_T*)(void *)cp->down.common) = *(cp->dpr); 铸造两次的原因是什么?为什么不直接对我的结构进行强制转换 要添加更多详细信息,请执行以下操作: typedef union download_s { MY_STRUCT_1_T *a1; MY_STRUCT_2_T *a2; void *common; } download_

在一个项目中,我看到了下面的一行,我不明白为什么要投两次

*((MY_STRUCT_T*)(void *)cp->down.common) = *(cp->dpr);
铸造两次的原因是什么?为什么不直接对我的结构进行强制转换


要添加更多详细信息,请执行以下操作:

typedef union download_s {
    MY_STRUCT_1_T *a1;
    MY_STRUCT_2_T *a2;
    void         *common;
} download_t;

typedef struct cp_s {
 ...
 MY_STRUCT_T *dpr;
 ...
} cp_t;

如果
cp->down.common
void*
已经对后者进行了强制转换(不需要对
(void*)
进行“内部”强制转换)

这将完成以下工作:

*((MY_STRUCT_T *) cp->down.common) = *(cp->dpr);

另一种情况是,如果
cp->down.common
被声明为
intptr\u t
,那么确实需要通过
void*
(如OP所示),因为只有
void*
才能保证适合
intptr\u t

C标准规定:

[intptr_t]使用任何有效的 指向void的指针可以转换为此类型,然后再转换回指向void的指针, 结果将与原始指针进行比较


我认为没有任何意义。对于许多程序员来说,C中的强制转换相当混乱,因此您不应该将强制转换的存在视为需要强制转换的指示

还有“太多”(=超过要求)括号,可以写为:

*(MY_STRUCT_T *) cp->down.common = *cp->dpr;

右侧也很好,
*
(指针解引用)的频率低于
->
(通过指针选择元素)。请一如既往地查看。

down.common的类型是什么?很可能是编码人员喜欢这种方式。一位同事建议可能需要正确对齐数据。这有意义吗?@mustafa:不,用两次投射来处理对齐问题是没有意义的。强制转换不需要更改实际指针值,只需更改其解释即可。(在不寻常的C实现中,强制转换可以更改指针值,但这里几乎肯定不会发生这种情况。)两个强制转换更常用于消除编译器警告;当您将
float*
直接转换为
int*
时发出警告的编译器可能不会在您先转换为
void*
然后再转换为
int*
时发出警告。但这里也不是这样,因为类型已经是
void*