首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是严格混叠规则中断的有效代码修复吗?

这是严格混叠规则中断的有效代码修复吗?
EN

Stack Overflow用户
提问于 2015-09-21 01:26:09
回答 1查看 116关注 0票数 3

我想构建/烧掉最新的Mellanox Flexboot固件到我的Infiniband ConnectX-3卡。然而,Mellanox没有提供二进制形式的最新版本。不过,他们确实提供了源代码。

不幸的是,当我试图编译它时,我会得到以下错误:

代码语言:javascript
复制
net/udp/dhcp.c: In function 'start_dhcp':
net/udp/dhcp.c:1361:3: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
   seed += *( ( uint32_t * )&netdev->ll_addr[j] );
   ^
cc1: all warnings being treated as errors
make: *** [bin/dhcp.o] Error 1
make: *** Waiting for unfinished jobs....
Build failed!

看看代码,下面的块就是问题所在。特别是种子线。这是因为严格的混叠是开着的,我们试图把一种类型作为另一种。

代码语言:javascript
复制
/**
 * Having both i and j , makes the code more robust
 * in the improbable case that MAX_LL_ADDR_LEN is not a
 * multiple of 4 bytes.
 */
for ( i = 0, j = 0; i < ( MAX_LL_ADDR_LEN >> 2 ); ++i, j += 4 ){
   seed += *( ( uint32_t * )&netdev->ll_addr[j] );
}

我的修正,这使得它编译。

代码语言:javascript
复制
for ( i = 0, j = 0; i < ( MAX_LL_ADDR_LEN >> 2 ); ++i, j += 4 ){
   uint32_t s;
   memcpy(&s, &netdev->ll_addr[j], 4);
   seed += s;
}

但在我把它烧了之前,这真的是等价物吗?我想应该是这样,但我只是想在我烧了这么重要的东西之前,先听听第二种意见。

FYI: ll_addr被定义为:

代码语言:javascript
复制
#define MAX_LL_ADDR_LEN 20

...

/** Link-layer address
 *
 * This is the current link-layer address assigned to the      
 * device.  It can be changed at runtime.
 */
 uint8_t ll_addr[MAX_LL_ADDR_LEN];

后来在这里使用种子:

代码语言:javascript
复制
 dhcp->xid = random ( seed );

 /* Store DHCP transaction ID for fakedhcp code */
 dhcp_last_xid = dhcp->xid;

所以在我看来,这个种子是用来给随机数发生器种种子的。我不太确定他们的种子方式是否是一个非常好的主意,但无论如何,它不应该伤害东西,我认为我的修复应该是好的,即使它给出了一个不同的答案。谢谢大家的回答。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-21 01:49:32

在这种情况下,只要ll_addr是一个char数组,您就安全了。j的增量保证每次只执行4个字节的增量,即uint32_t的宽度。

在这种情况下,最好使用原始实现而忽略错误,特别是如果代码是在C99之前编写的。

洛尔黑德对恩典也有很好的见解。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32686091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档