C++返回本地字符串字面量的string_view为何不会触发警告?
问题核心原因分析
二者本质是存储期完全不同的两类对象:
普通字符串字面量(
"hello"、"hey",无自定义后缀)
属于静态存储期对象,在程序启动时就分配在只读常量区,生命周期和整个程序运行周期完全一致,不会在函数退出时被销毁。
你的to_stringview返回std::string_view,本质是持有指向字符串首地址的指针+长度,指向这个静态存储的字面量,完全不存在悬空问题,因此编译器不会报任何警告,运行也是合法的。带
s后缀的字符串字面量("hey"s)
是C++标准库定义的用户自定义字面量,执行时会在函数栈上生成一个临时的std::string对象,这个临时对象的生命周期仅限当前表达式,函数返回后会立刻被销毁。你用const std::string&返回值绑定这个临时对象,函数退出后引用就指向了已经被销毁的栈内存,属于典型的悬空引用,因此编译器会触发警告。
补充说明
你第一段代码里的to_string返回"hey"也是合法的:这里相当于用静态存储的字符串字面量构造了一个新的std::string对象,按值返回做了移动/拷贝,不存在生命周期问题。
如果你把to_stringview的返回值改成指向局部std::string的内容,比如下面的写法,就会触发编译器警告了:
std::string_view to_stringview() const noexcept { std::string s = "hello"; return s; // 指向局部std::string的内部缓冲区,函数退出后缓冲区销毁,string_view悬空 }
内容的提问来源于stack exchange,提问作者MatG
相关产品推荐
相关产品推荐

