我正在编写一些代码(在FPGA上运行),它将模式写入由其基地址和最高地址指定的内存块。数据宽度为64位,地址空间为32位。在我的系统上,long是32位,long long是64位。代码看起来像这样:
unsigned long base_addr = 0xC0000000;
unsigned long high_addr = 0xFFFFFFFF;
unsigned long long i;
for(i = base_addr; i <= high_addr; i += 4){
*((unsigned long *) i) = some_pattern;
}
一切正常但我从编译器得到了“从不同大小的整数转换为指针”警告。如果我使用32位迭代器变量,代码无限循环,因为迭代器命中0xFFFFFFFC然后再次溢出回来。
有更好的方法吗?我知道有很多方法可以毫无问题地使用32位迭代器(检测/预测溢出,从high_addr中减去3)但我认为这段代码最简单,最易读。编写具有已知编译器错误的代码会被认为是不好的风格吗?
答案 0 :(得分:2)
为什么要将i
声明为unsigned long long
?有什么意义呢?
正如您所说,您平台上的地址是32位。将i
声明为unsigned long
,就像base_addr
和high_addr
一样。警告应该消失。
同时,“数据宽度是64位”是什么意思?如果数据(和模式)实际上是64位,那么你应该做
for (i = base_addr; i <= high_addr; i += 8){ /* or i += sizeof(unsigned long long) */
*((unsigned long long *) i) = some_pattern;
}
另外,请注意,例如,如果i
在迭代期间变得等于high_addr
,则您的循环体仍将执行,访问超出high_addr
的7个额外字节。这是意图吗?
答案 1 :(得分:2)
我想要更好的方法:
unsigned long long *base_addr = (unsigned long long *)0xC0000000;
unsigned long long *high_addr = (unsigned long long *)0xFFFFFFFF;
unsigned long long *i;
for (i = base_addr; i < high_addr; ++i) {
*i = some_pattern;
}
如果i < base_addr
也可以通过中止for循环,可能需要小心指针(i)环绕。