【问题标题】:Using 64 bit integer iterator for 32 bit address space?对 32 位地址空间使用 64 位整数迭代器?
【发布时间】:2013-01-29 17:26:00
【问题描述】:

我正在编写一些代码(在 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,然后再次溢出回 0。

有没有更好的方法来做到这一点?我知道有很多方法可以毫无问题地使用 32 位迭代器(检测/预测溢出,从 high_addr 中减去 3),但我认为这段代码是最简单和最易读的。编写带有已知编译器错误的代码是否被认为是不好的风格?

【问题讨论】:

    标签: c memory integer compiler-warnings


    【解决方案1】:

    为什么将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 个额外字节。是这个意图吗?

    【讨论】:

      【解决方案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 &lt; base_addr 也是,可能需要小心指针 (i) 回绕,通过中止 for 循环。

      【讨论】:

        猜你喜欢
        • 2012-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-11
        • 1970-01-01
        • 2019-03-25
        • 1970-01-01
        • 2020-03-24
        相关资源
        最近更新 更多