【问题标题】:Are address offsets resolved during compile time in C/C++? [closed]在 C/C++ 的编译期间是否解决了地址偏移? [关闭]
【发布时间】:2012-07-14 12:38:02
【问题描述】:
void *p = malloc(1000);
*((int*)p) = 666;
*((int*)p+sizeof(int)) = 777;
int i;
for (i = 0; i<10; ++i)
    printf("%d ", *((int*)p+sizeof(int)*i));

手动偏移是在编译时解决的,还是会增加运行时执行算术运算的开销?

【问题讨论】:

  • 你为什么不看看组装出来的自己来判断呢?目前尚不清楚您在谈论什么偏移量,这可能取决于您的编译器和优化设置。
  • 我说的是p指针地址的偏移量。
  • 其中三个,一个在循环中。我上面的评论也适用:检查你的编译器产生了什么。
  • 那是一些相当可怕的代码......
  • @Mat - 我特意提出了 3 个不同的场景来说明这一点。我不太擅长阅读汇编,这就是我在这里问的原因。

标签: c++ c memory offset resolve


【解决方案1】:

即使你有一个常量而不是sizeof(int),编译器也无法提前知道p 中的地址,所以它必须进行加法运算。如果你有类似i = sizeof(int)+4 的东西,那么它应该优化编译时间并直接将i 设置为8

另外,我认为当你这样做时:

*((int*)p+sizeof(int)) = 777;

你的意思是:

*((int*)p + 1) = 777; /* or ((int*)p)[1] = 777; */

同样printf("%d ", *((int*)p+sizeof(int)*i));应该是:

printf("%d ", *((int*)p + i));

【讨论】:

    【解决方案2】:

    sizeof(int) 在编译时肯定是已知的,因此有效地利用这些信息很有意义。但是,不能保证给定的编译器会生成如下内容:

    mov dword [ebx+16], 777
    

    而不是这样的:

    mov ecx, 16
    mov dword [ebx+ecx], 777
    

    lea ebx, [ebx+16]
    mov dword [ebx], 777
    

    甚至

    add ebx, 16
    mov dword [ebx], 777
    

    【讨论】:

      猜你喜欢
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      相关资源
      最近更新 更多