调用带有取消引用指针的引用的函数的成本是多少?

问题描述 投票:0回答:1

在以下类型的代码中从指针转换为 ref 是否有任何成本?

void bar(Obj&);

void foo(Obj* o) {
    bar(*o); 
}

一方面,指针的值是

Obj
的地址,因此编译器可以将该值重新解释为引用。然而,如果
o
是一个空指针,那么该 deref 就会崩溃,因此,大概那里有一个内存读取。编译器没有关于指针是否有效的上下文。

我知道在某些情况下,当编译器在转换附近有足够的上下文时,它可以省略转换的读取。

我发现了另一个问题,但该答案适用于不同的场景:将指向向量的指针转换为引用的成本

c++ reference compiler-optimization abi
1个回答
2
投票

实际上,此操作没有任何成本。 为了可视化这一点,您可以在启用优化的情况下编译以下代码:

struct Obj;

void bar(Obj&);

void foo(Obj* o) {
    bar(*o); 
}

GCC 将其编译为

foo(Obj*):
        jmp     bar(Obj&)

在 ABI 级别,指针和引用都作为它们所引用的对象的内存地址进行传递,因此它们可以互换,无需任何操作。

但是,如果

o
nullptr
,那么该 deref 就会崩溃,因此,据推测,那里读取了内存。

不,这不一定会发生。 如果

o
是空指针,则取消引用它是未定义的行为。 这并不意味着程序必须崩溃;而是意味着程序必须崩溃。这只是意味着在这种情况下任何事情都可能发生。 在这种情况下,它会导致引用绑定到不是实际对象的东西,这是不可能的。这可能会进一步破坏一些代码。

我知道,在某些情况下,当编译器在转换附近有足够的上下文时,它可以省略转换的读取。

此代码中既没有读取也没有转换,至少在 C++ 标准意义上是这样。 取消引用指针不会从所指向的对象中读取,并且绑定引用不被视为转换。

© www.soinside.com 2019 - 2024. All rights reserved.