为参考参数和优化更改创建临时对象

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

我有以下代码

#include <iostream>

void foo(const int* const &i_p) {
    std::cout << &i_p << std::endl;
}

int main () {

    int i = 10;
    int* i_p = &i;
    std::cout << &i_p << std::endl;
    foo(i_p);
}

打开

x86-64 clang 9.0.0
,输出为

Program returned: 0
0x7ffc43de63f8
0x7ffc43de6400

x86-64 clang 10.0.0
编译器资源管理器链接时,输出变为

Program returned: 0
0x7ffc9da01ef0
0x7ffc9da01ef0

这里进行了什么优化来提供相同的地址?我相信应该实现一个临时对象,因为我们无法将低级

const
指针绑定到低级
non-const

c++ clang++
1个回答
0
投票

当前措辞

您只有一个

i_p
指针,自然地,
&i_p
中的
main
&i_p
中的
foo
应该产生相同的地址。

const int * const
int *
引用兼容
,因为指向
int*
的指针,即
int**
可以通过
限定转换
转换为 const int * const*。 因此,对
const int * const
的引用可以绑定到
int*

没有什么需要创建第二个对象,至少在当前草案中不需要。然而,过去并不总是这样,并且在引用绑定期间并不总是考虑资格转换。

解释您观察到的行为的历史缺陷

CWG2018。限定转换 vs 引用绑定 指出不考虑限定转换并创建临时对象,如本例所示:

const int &&x1 = make<int&&>();         // ok, binds directly
const int *const &&x2 = make<int*&&>(); // weird, binds to a temporary
const int *&&x3 = make<int*&&>();       // weird, binds to a temporary

这个例子与你的类似。 如果

const int* const &i_p
不是简单地绑定到
i_p
中的
main
而是在调用
foo
时创建一个全新的临时指针,那么它将是一个单独的对象。请注意,由于临时物化,
const&
可以绑定到临时对象。

这种行为是一个缺陷,而且看起来并不是故意的。 这个缺陷似乎已在 GCC 7 和 clang 10 中得到解决,这就是为什么您不再看到创建两个单独的指针。

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