C++ 假设我们有一个右值引用,右值是持久的吗?
下面是一个使用boost::typeindex::type_id_和_cvr推断变量类型的示例 包括 包括 包括 包括C++ 假设我们有一个右值引用,右值是持久的吗?,c++,C++,下面是一个使用boost::typeindex::type_id_和_cvr推断变量类型的示例 包括 包括 包括 包括 define PRINT_TYPEx std::coutw指反汇编的前两行中的临时堆栈对象。临时语句的生命在语句末尾结束。这使得w成为一个悬而未决的引用。这个相同的内存地址稍后会被重用,请参见反汇编中标记为1de4的行,它覆盖了存储在那里的1。另一个现象是,当我们使用自动类型推断时,会忽略所有引用,实际上会发生值复制 #include <memory> #inclu
define PRINT_TYPEx std::coutw指反汇编的前两行中的临时堆栈对象。临时语句的生命在语句末尾结束。这使得w成为一个悬而未决的引用。这个相同的内存地址稍后会被重用,请参见反汇编中标记为1de4的行,它覆盖了存储在那里的1。另一个现象是,当我们使用自动类型推断时,会忽略所有引用,实际上会发生值复制
#include <memory>
#include <iostream>
#include <boost/type_index.hpp>
#include <cstdio>
#define PRINT_TYPE(x) std::cout << "type of " #x " is " << \
boost::typeindex::type_id_with_cvr<decltype(x)>().pretty_name() << std::endl
int main(){
int x = 1;
int *y = &x;
auto w = std::move(1);
printf("w=%x\n",w);
PRINT_TYPE(x);
printf("w=%x\n",w);
return 0;
}
int&&w=1;将延长临时文件的使用寿命
move返回一个右值引用,因此,不会对
int&&w=std::move1
w在语句末尾悬空。所以访问它是UB
int&& w = std::move(1);
1d99: c7 45 b0 01 00 00 00 movl $0x1,-0x50(%rbp) # <- **-0x50(%rbp) is the address of rvalue 1**
1da0: 48 8d 45 b0 lea -0x50(%rbp),%rax
1da4: 48 89 c7 mov %rax,%rdi
1da7: e8 34 06 00 00 callq 23e0 <_ZSt4moveIiEONSt16remove_referenceIT_E4typeEOS1_>
1dac: 48 89 45 b8 mov %rax,-0x48(%rbp)
...
PRINT_TYPE(x);
1dc9: 48 8d 35 64 12 00 00 lea 0x1264(%rip),%rsi # 3034 <_ZStL6ignore+0x23>
1dd0: 48 8d 3d 49 32 20 00 lea 0x203249(%rip),%rdi # 205020 <_ZSt4cout@@GLIBCXX_3.4>
1dd7: e8 24 fd ff ff callq 1b00 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
1ddc: 48 89 c3 mov %rax,%rbx
1ddf: e8 5e 09 00 00 callq 2742 <_ZN5boost9typeindex16type_id_with_cvrIiEENS0_14stl_type_indexEv>
1de4: 48 89 45 b0 mov %rax,-0x50(%rbp) # <- **-0x50(%rbp) is modified**
1de8: 48 8d 45 c0 lea -0x40(%rbp),%rax
1dec: 48 8d 55 b0 lea -0x50(%rbp),%rdx
1df0: 48 89 d6 mov %rdx,%rsi
1df3: 48 89 c7 mov %rax,%rdi
1df6: e8 13 04 00 00 callq 220e <_ZNK5boost9typeindex14stl_type_index11pretty_nameB5cxx11Ev>
1dfb: 48 8d 45 c0 lea -0x40(%rbp),%rax
1dff: 48 89 c6 mov %rax,%rsi
1e02: 48 89 df mov %rbx,%rdi
1e05: e8 e6 fc ff ff callq 1af0 <_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@plt>
1e0a: 48 89 c2 mov %rax,%rdx
1e0d: 48 8b 05 bc 31 20 00 mov 0x2031bc(%rip),%rax # 204fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
1e14: 48 89 c6 mov %rax,%rsi
1e17: 48 89 d7 mov %rdx,%rdi
1e1a: e8 21 fd ff ff callq 1b40 <_ZNSolsEPFRSoS_E@plt>
1e1f: 48 8d 45 c0 lea -0x40(%rbp),%rax
1e23: 48 89 c7 mov %rax,%rdi
1e26: e8 45 fc ff ff callq 1a70 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>
#include <memory>
#include <iostream>
#include <boost/type_index.hpp>
#include <cstdio>
#define PRINT_TYPE(x) std::cout << "type of " #x " is " << \
boost::typeindex::type_id_with_cvr<decltype(x)>().pretty_name() << std::endl
int main(){
int x = 1;
int *y = &x;
auto w = std::move(1);
printf("w=%x\n",w);
PRINT_TYPE(x);
printf("w=%x\n",w);
return 0;
}
w=1
type of x is int
w=1