我想在我的Infiniband ConnectX-3卡上构建/刻录最新的Mellanox Flexboot固件。但是,Mellanox尚未提供二进制形式的最新版本。但他们提供了源代码。
不幸的是,当我尝试编译它时,我收到以下错误:
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!
查看代码,以下块是问题所在。特别是种子线。这是因为严格的别名已经开启,我们正在尝试将一种类型作为另一种类型进行访问。
/**
* 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] );
}
我的修复使它编译。</ p>
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;
}
但在我烧之前,这实际上是等同的吗?我认为应该是这样,但在我烧掉一些非常重要的东西之前,我只是想要第二个意见。
供参考: ll_addr定义为:
#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];
种子后来在这里使用:
dhcp->xid = random ( seed );
/* Store DHCP transaction ID for fakedhcp code */
dhcp_last_xid = dhcp->xid;
因此,在我看来,这个种子的东西只是用来为随机数生成器播种。我不确定他们种下它的方式是不是一个非常好的主意,但是它不应该伤害事情,我认为我的修复应该没问题,即使它给出了不同的答案。所以,谢谢大家的答案。
答案 0 :(得分:2)
在这种情况下,只要char
是j
的数组,您就是安全的。 uint32_t
的增量保证增量一次只执行四个字节,即onError
的宽度。
在这种情况下,最好使用原始实现并忽略错误,特别是如果代码是在C99之前编写的。
Lorehead在关于字节序方面也提出了一个很好的观点。