gpt4 book ai didi

c++ - 关于运算符 -> 和 () 的评估顺序

转载 作者:行者123 更新时间:2023-11-30 02:36:25 25 4
gpt4 key购买 nike

考虑这个代码片段:

std::shared_ptr<...> p = ...;
p->f(std::move(p));

根据 cppref , operator ->() 具有相同的优先级并且都是从左到右关联的。所以我假设 p->std::move() 之前被评估,并且该片段应该没问题。但 VC15 却反其道而行之,使我的程序崩溃。这是一个 VC15 错误还是我这里有问题?

最佳答案

您正在调用未定义的行为,因为标准指定函数调用中参数的求值顺序,并且...

p->f(std::move(p));

您有两个 参数被传递。首先,this ,其次,std::move(p) .但是现在,有一个不太明显的问题。您同时读取写入同一个共享指针。这基本上可以导致任何事情,也就是所谓的未定义行为。更不用说您正在使用 std::move()在这样的指针上...

*this指向 *p , 但第一个(明确的)参数现在包含指针本身,所以 *p无效!让我们假设这并没有使程序崩溃(不知何故......)。然后,这会导致对象本身在 f 时被销毁。离开了。但是......当共享指针(假设只留下一个引用)并因此对象本身被销毁时,函数没有仍然存在。同样,只是问题...

这只是一个例子,任何事情都可能发生。只是不要用相同的表达式阅读,你会没事的:)。

顺便说一句:We all know VS is all but standards-complaint , 但无论如何,这与运算符解析的顺序和优先级无关。

编辑:一切正常if f()采用通用引用(又名:转发引用,又名折叠右值引用黑魔法,以某种方式进入标准)或右值引用。所以,例如……

void f(std::shared_pointer<...> &&ptr)

一切都会变得美丽和完美,只要你不对ptr做坏事| ...

但是,如果f接受类型为 std::remove_reference_t<decltype(*p)>> 的对象,共享指针被移到它的参数上,所有上述事情都会发生。

关于c++ - 关于运算符 -> 和 () 的评估顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32793875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com