提问人:Noah Bishop 提问时间:12/17/2020 更新时间:12/17/2020 访问量:224
强制 C++ 为参数分配新地址
Force C++ to assign new addresses to arguments
问:
似乎当我将不同的整数直接传递给函数时,C++ 会为它们分配相同的地址,而不是将不同的地址分配给不同的值。这是设计使然,还是可以关闭的优化?有关说明,请参阅下面的代码。
#include <iostream>
const int *funct(const int &x) { return &x; }
int main() {
int a = 3, b = 4;
// different addresses
std::cout << funct(a) << std::endl;
std::cout << funct(b) << std::endl;
// same address
std::cout << funct(3) << std::endl;
std::cout << funct(4) << std::endl;
}
这个问题的更大背景是,我正在尝试构造一个指向整数的指针列表,我将逐个添加这些指针(类似于 )。由于我无法修改方法定义(类似于 的),我想存储每个参数的地址,但它们最终都具有相同的地址。funct(3)
funct
答:
该函数接受绑定到变量的引用。const int *funct(const int &x)
int
a
并且是变量,因此可以绑定到它们,并且它们将具有不同的内存地址。b
int
x
由于该函数接受常量引用,这意味着编译器也允许绑定到临时变量(而非常量引用不能绑定到临时变量)。x
int
当您将数字文本传递给 时,例如 ,编译器会创建一个临时变量来保存文本值。该临时变量仅在进行函数调用的语句的生存期内有效,然后临时变量超出范围并被销毁。x
funct(3)
int
因此,当您在单独的语句中进行多次调用时,编译器可以自由地为这些临时变量重用相同的内存,例如:funct()
// same address
std::cout << funct(3) << std::endl;
std::cout << funct(4) << std::endl;
实际上等同于:
// same address
int temp;
{
temp = 3;
std::cout << funct(temp) << std::endl;
}
{
temp = 4;
std::cout << funct(temp) << std::endl;
}
但是,如果在单个语句中多次调用,编译器将被迫创建单独的临时变量,例如:funct()
// different addresses
std::cout << funct(3) << std::endl << funct(4) << std::endl;
实际上等同于:
// different addresses
{
int temp1 = 3;
int temp2 = 4;
std::cout << funct(temp1) << std::endl << funct(temp2) << std::endl;
}
评论
cout << funct(3) << funct(4)
cout << funct(3) << funct(3)
funct(3) << funct(4)
3
4
;
3
4
funct(3) << funct(3)
函数
const int *funct(const int &x) { return &x; }
将返回所引用的任何内容的地址。x
因此,正如您所期望的那样,这将打印以下地址:a
std::cout << funct(a) << std::endl;
表达式的问题在于,不可能引用常量并将其作为参数传递。常量没有地址,因此出于实际原因,C++ 不支持引用常量。C++ 实际支持的是创建一个临时对象,用值初始化它,并获取该对象的引用。funct(3)
3
基本上,在这种情况下,编译器将翻译以下内容:
std::cout << funct(3) << std::endl;
变成与此等效的东西:
{
int tmp = 3;
std::cout << funct(tmp) << std::endl;
}
除非您采取一些措施来延长临时对象的生存期,否则它将在函数调用后(或在下一个序列点之前,我不确定)超出范围。
由于在创建临时 from 之前,创建的临时内存超出了范围,因此第一个临时使用的内存可能会被重新用于第二个临时内存。3
4
评论
funct
评论
3
&x
x
x
x
const