这需要“额外”的铸造吗?

时间:2011-03-09 16:09:06

标签: c casting

情况:

typedef unsigned int u32;
typedef unsigned char u8;

const u8 *x;
...
var = (u32)(*(const u32 *)x);

var应该包含一个DWORD大小的值。我对上述任务说明的了解是:

  1. x首先是指向u8大小的指针 值。
  2. 然后
  3. x被转换为指向a u32大小的值,所以我们有:(const u32 *)x。
  4. 然后在
  5. 中取消引用x 为了得到32位的值 它指向的是,我们有: *(const u32 *)x
  6. 然后将取消引用的数据强制转换为u32 大小
  7. 所以最后,问题是:我认为在上面的#3中,取消引用会说我们从它获得的值是32位大小,所以如果是这样,那么为什么会有额外的强制转换(显式?)表示取消引用的值是32位?如果只是执行上面的步骤1到3,而不是必须执行第4步,那不是吗?

    感谢您澄清!

3 个答案:

答案 0 :(得分:2)

是的,最终(u32)演员阵容是多余的。

答案 1 :(得分:1)

最终演员阵容没问题,因为你在任务的RHS上使用它。

*运算符不行。这可能会给你双重未定义的行为:

  • 你访问超出它的对象 边界
  • char通常与其他整数类型的对齐方式不同。

答案 2 :(得分:0)

在这种情况下,最终的演员阵容是不需要的。以下表达式:

(*(const u32 *)x)

返回“const u32”值。由于您将此值分配给变量(可能是u32变量),因此您可以复制“const u32”值,并且此副本不需要是const。您自己决定是否希望您刚制作的副本应该是const。所以这是有效的:

u32 var = *(const u32 *)x;

但这也是有效的:

const u32 var = *(const u32 *)x;

但是在这种情况下,你无法在赋值后再更改var的值。

请注意,此声明无效:

u32 &var = *(const u32 *)x;

在这种情况下,您没有复制,但是您正在为x变量的内容创建var别名,如果表达式的结果是const,则您的别名也应该是const。

编译器可能会给出如下错误消息:

cannot convert from 'const u32' to 'u32 &'

相反,你必须写下这个:

const u32 &var = *(const u32 *)x;