gpt4 book ai didi

c++ - 在旧的 C++ 编译器上 `* const&` 中的临时引入令人费解

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:01:45 29 4
gpt4 key购买 nike

在使用较旧的 C++ 编译器的平台上构建时,我注意到在其他地方运行良好的代码出现意外行为。我不确定这是否表示旧编译器中存在错误,或者标准发生了一些变化,但我一直明确地使用 C++11 进行构建。

特别是,较旧的编译器似乎对 * const& 使用一个临时的,而我不希望它这样做,并且当它的堆栈帧被清理和覆盖时,该临时的会导致 SIGSEGV .

这是我从原始代码中提取 MWE 的最大努力。我的问题围绕类 C 的构造函数:

#include <stdio.h>

struct A {
int* i;
};

class B {
public:
int* const& i_ptr_const_ref; // normally not public
B(int* const& i_ptr) : i_ptr_const_ref(i_ptr) {}
operator int* const& (void) const { return i_ptr_const_ref; }
};

int null_b = { 0 };
int* null_b_ptr = &null_b;
int* const& null_b_ptr_const_ref = null_b_ptr;

class C {
public:
B b;
// C(const A* a_ptr) : b(a_ptr ? a_ptr->i : null_b_ptr_const_ref) {} // this works
C(A* a_ptr) : b(a_ptr ? a_ptr->i : null_b_ptr_const_ref) {} // this fails
// C(A* a_ptr) : b(a_ptr ? (int* const&) a_ptr->i : null_b_ptr_const_ref) {} // this works
// C(A* a_ptr) : b(a_ptr->i) {} // this works
};

int main(void) {
A a;
A* a_ptr = &a;
a_ptr->i = (int*) 42;
C c(a_ptr);
printf("c.b.i_ptr_const_ref = %p\n", (void*) c.b.i_ptr_const_ref);
printf("c.b= %p\n", (void*) c.b);
printf("a_ptr->i= %p\n", (void*) a_ptr->i);
return 0;
}

Try it on Compiler Explorer

我打印出的值应该全部匹配,但是在 5.1 之前的 GCC 编译器和 18 之前的 ICC 编译器上(我知道英特尔以与其他编译器的“bug-for-bug”兼容性而自豪),中间那个显示堆栈地址而不是预期值。我能够尝试正确运行的所有版本的 Clang 和 ELLCC 编译器。

未注释的 C 构造函数是我想使用的构造函数,但它无法正常工作。如果我将 A* a_ptr 参数设置为 const,我将在 MWE 中得到预期的结果,但在更大的代码库中我不能这样做。如果我在初始化程序中不使用 ?:,或者如果我在初始化程序中显式地将 a_ptr->i 转换为 int,我也会得到预期的结果* const&,但我不明白为什么我必须这样做。

我原以为用 int* 初始化 int* const& 会很好,但我最好的猜测是 ?: 以某种方式混淆了编译器。任何人都可以帮助我了解旧的 GCC 和 ICC 编译器在这里是否不正确,或者我是否误解了这种语言?

最佳答案

这很明显是一个编译器错误:int* 类型的左值当然可以隐式转换为 int* const&,因此条件运算符的结果应该是一个左值。

printf 输出看起来很神秘,但实际上是该错误的直接结果:即使 first 读取 c.b.i_ptr_const_ref(它当然是透明遵循的引用)正在从死的临时读取,但它尚未被覆盖并且仍然包含 a.i拷贝。在第一个 printf 之后,该内存已被破坏并恰好保存了一个堆栈地址。

关于c++ - 在旧的 C++ 编译器上 `* const&` 中的临时引入令人费解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58479335/

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