2016-08-17 54 views
3

假设我有此数组:当我将uint8_t数组转换为uint32_t时会发生什么?

uint8_t arr[10]; 

位于地址0x00

然后我想将它的一部分分配给uint32_t的值。 arr [1],arr [2],arr [3]和arr [4]的聚合为32位整数。这里有一个例子:

uint8_t arr[10]; 
uint32_t i; 
i = *((uint32_t *)&arr[1]); 

让我困扰的是,arr[1]位于地址而不是多个四(在地址0x01)。所以问题是:在32位平台上会发生什么?这是否合法,是否与标准uint32作业相比有一些缺点?

+4

行为是不确定之间进行切换;任何事情都可能发生,包括'程序崩溃'和'程序似乎工作'。 –

+0

@bolov失败,thx –

回答

5

这是违法的,因为它打破了严格的别名规则,导致undefined behaviour

使用memcpy代替:

memcpy(&i, &arr[1], sizeof(i)); 

但是千万注意,此代码假定主机字节。如果您需要独立于代码的代码,请使用位移和掩码将4个值合并为整数,或在memcpy之后交换字节(编译器通常会为此提供某种内在的引用)。

0

这不确定的行为由于重叠规则,你可以使用赋值:

i = arr[1]; 

其中uint8_t值转换为uint32_t值。

3

类型双击违反了C标准的有效类型规则,第6.5节第6和7段。这些表示您无权访问与声明不同类型的对象。 (这些规则有一些复杂的例外情况,但在这里不适用。)

这样做会让您的程序处于未定义的状态,并且可能发生不好的事情。作为一个经验法则,除非你确切地知道你在做什么,否则绝对不要做指针转换。

如果你真的需要字节表示与另一种类型的最简单的方法是使用工会

union twist { 
    unsigned char c[sizeof(uint32_t)]; 
    uint32_t u; 
} val = { .c = { [0] = 7, } }; 

// now use 
val.u 
相关问题