【问题标题】:C++ Pointer access similar to assembly类似于汇编的 C++ 指针访问
【发布时间】:2012-09-10 16:07:59
【问题描述】:

有时我在 C++ 中看到不同的数组访问样式,并认为它可能与程序集寻址模式有关:

C++:

int * aa=new int[2];
0[aa]=15; //a little different than aa[0]
1[aa]=15;
aa[0]=15;
aa[1]=15;
printf("%d %d \n",aa[0],aa[1]);

组装:

__asm
{
    mov aa[0],ebx
    mov aa[1],eax
    mov 0[aa],ebx
    mov 1[aa],eax
}

这种 C++ 数组访问表示法是标准吗?如果是,它是从程序集寻址模式派生的吗?

当我尝试 [aa]1=5; 时,编译器给出了

  • “未找到aa属性”,
  • “缺少';'在“常数”之前”
  • “左操作数必须是左值”。

    //当我尝试指针运算时,

    *(aa+1)=0//不报错

    *(aa+0)=0//没有错误:)

运算符 [] 重载的规则是否相同?

MSVC++ 2010

谢谢。

【问题讨论】:

  • 两者无关 - C 比 80x86 早了很多年。
  • 你在哪里看到像0[aa]=15这样的东西在真正的C++代码中?这是合法的,但大多数人不会使用它,除非他们抽的是不合法的东西

标签: c++ arrays pointers assembly


【解决方案1】:

这是 C 和 C++ 的一个众所周知的怪癖,它们并不真正关心表达式的哪一半放在方括号 [] 中。它们都计算为相同的等效表达式:

*(0+aa)=15;

【讨论】:

  • 运算符重载 [] 怎么样?
  • 运算符重载在这里是完全正交的,因为它允许在使用 [] 运算符时调用任何行为。
  • @slugonamission:但是,重载必须是非静态类成员,因此您通常不能定义重载使得0[aa] 等价于aa[0]
  • @MikeSeymour - 当然,我只是想说明您不能将重载的 [] 运算符与 C 默认的 [] 运算符进行对比
【解决方案2】:

表达式a[b] 基本上被翻译成*(a+b)。 这就是为什么这种“风格”11[arr] 是可能的。

[aa]11 失败的原因纯粹是句法。

【讨论】:

    【解决方案3】:

    这种 C++ 数组访问表示法是标准吗?

    是的。只要一个操作数是指针,另一个是算术,a[b] 就等价于*(a+b),所以无论是指针还是索引进入[] 内部都没有关系。

    如果是,它是否源自程序集寻址模式?

    几乎肯定不会。语法直接来自 C,它最初是为 PDP 系列计算机开发的,其中汇编寻址模式被编写为1(aa)

    当我尝试[aa]1=5 时,编译器给出(错误)

    这是因为下标表达式的语法被指定为postfix-expression [ expression ],所以[]中的操作数必须在另一个之后。

    对于运算符 [] 重载,这条规则是否相同?

    没有。如果运算符已重载,则a[b] 等效于a.operator[](b),而不是b.operator[](a)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 2011-07-08
      • 2021-08-26
      相关资源
      最近更新 更多