使用64位整数迭代器来获得32位地址空间?

时间:2013-02-14 00:33:16

标签: c memory integer compiler-warnings

我正在编写一些代码(在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)但我认为这段代码最简单,最易读。编写具有已知编译器错误的代码会被认为是不好的风格吗?

2 个答案:

答案 0 :(得分:2)

为什么要将i声明为unsigned long long?有什么意义呢?

正如您所说,您平台上的地址是32位。将i声明为unsigned long,就像base_addrhigh_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)环绕。