当我取消引用指针以通过引用传递指针时,在编译器级别会发生什么?[已结束]

What happens at the compiler level when I dereference a pointer to pass it by reference? [closed]

提问人:Omroth 提问时间:6/26/2023 更新时间:6/26/2023 访问量:120

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

5个月前关闭。

我感兴趣的是,当我显式取消引用指针以通过引用传递指针时,编译器会做什么:

void foo(A& arg)
{
   arg.member = 7;
}

void goo()
{
   A* ob = new A();
   foo(*ob);
   printf(ob->member); // should show 7
}

我之所以感兴趣,是因为我相信将取消引用从函数调用中移除会产生非常不同的行为:

void foo(A& arg)
{
   arg.member = 7;
}

void goo()
{
   A* ob = new A();
   A ob_dereferenced = *ob;
   foo(ob_dereferenced);
   printf(ob->member); // should show whatever A initialises member to
}
C++ 按引用传递

评论

6赞 463035818_is_not_an_ai 6/26/2023
A ob_dereferenced = *ob;创建副本。这不是代码的第一个版本所做的
1赞 Stephen Newell 6/26/2023
你检查过组件了吗?这可以肯定地告诉你发生了什么,包括当你改变优化级别时。
0赞 Omroth 6/26/2023
好的,所以创建副本的是“A ob_dereferenced =”。 *ob 只是参考。谢谢,也许这个问题太简单了。
2赞 Pepijn Kramer 6/26/2023
在某种程度上,编译后的代码可能看起来相同或非常相似(引用也是指针,只是有一些额外的规则来说明如何使用它们,并且它们承诺引用一个有效的对象)
1赞 Peter 6/26/2023
@Botje 这不一定是真的。如果在初始化后重新分配(指向不同的对象),则后续的用法仍将引用原始指针。否则的编译器将是一个有缺陷的编译器。obob_dereferencedob_dereferenced

答:

1赞 463035818_is_not_an_ai 6/26/2023 #1

您的比较不公平,因为在第二个版本中:

void goo()
{
   A* ob = new A();
   A ob_dereferenced = *ob;   // <---- here !!!
   foo(ob_dereferenced);
   printf(ob->member); // should show whatever A initialises member to
}

您正在创建实例的副本。根据具体情况,创建第二个实例可能会产生可观察到的副作用。AA

但是,让我们把这种可观察到的副作用放在一边,并使用

 struct A { int member = 0; };

那么两者之间没有可观察到的差异:

 void moo(A* a) { 
      foo(*a);    
 }

并使用本地引用:

 void moo(A* a) { 
      A& b = *a;  
      foo(b);
 }

这两个人做同样的事情。当启用优化时,没有理由期望编译器的输出不同。moo

PS:您的两个版本都泄漏内存。如果需要示例的指针,则不需要 .例如,弥补了一个完全精细的指针,您无需担心泄漏。在上面,我通过简单地假设指针来自某个地方来避免这个问题。newA a; A* aptr = &a;A