有没有办法在从临时返回按值string_view时获得编译器警告?

Is there a way to get a compiler warning when returning a by-value string_view from a temporary?

本文关键字:view 警告 编译器 string 有没有 返回      更新时间:2023-10-16

我一直在通过将 c++17 更改应用于一些旧代码来学习它们,并发现返回std::string_view会产生静默错误,在我看来,引用临时编译器警告是合适的。 有没有办法生成一个?

我正在使用 g++ 9.3.0,带有编译器标志-ggdb -Wall -std=c++17. 我还在没有警告的情况下尝试了叮当声和叮当声/叮当声。

首先,我最近了解到,最好只使用std::string_view来替换参数中的const std::string &,而不是作为返回值。 这篇文章向我解释得很好。 不幸的是,我没有看到它通常以这种方式呈现,所以我想知道其他人是否也有同样的问题。

(以下代码中的第 1 节( 我知道尝试返回对临时字符串的非常量引用将无法编译。 无论该引用是std::string &还是std::string_view &,都是如此。

如果我尝试返回对永久字符串theString的非常量std::string_view &引用,则会发生相同的编译器错误。

(以下代码中的第 2 节( 我也知道,如果我尝试返回对临时字符串的 const 引用,它将编译,但编译器会提供一个警告,指出我已返回对临时字符串的引用。 与第1节一样,无论该引用是const std::string &还是const std::string_view &,情况都是一样的。

同样与第 1 节一样,如果我尝试返回对永久字符串theStringconst std::string_view &引用,则会发生对临时编译器警告的相同引用。

(以下代码中的第 3 节( 如果我尝试从永久或从对永久的引用返回std::string_view,它当然可以正常工作,但是如果我尝试从临时返回,它会在没有警告的情况下编译,但它的使用会产生垃圾。

编译器不应该生成与代码第 2 节中相同的对临时警告的引用吗? 当然,它本身不是一个参考,但theString不是临时的,并且在那里应用了该警告。 有没有办法生成这样的警告? 也许我缺少 g++ 或 clang-tidy 的编译器选项?

#include <string>
#include <string_view>
#include <iostream>
class C1
{
public:
C1() { theString = "Initial string."; }
//  produce a temporary std::string
std::string getS() { return theString; }
//  Returning string_view works fine if called on a reference to a permenant string.
std::string &getRef() { return theString; }
//  SECTION1: These won't compile: can't bind non-const lvalue reference to the rvalue
//     std::string &getSref() { return getS(); }
//     std::string_view &getSVref() { return getS(); }
//     std::string_view &getSVref() { return theString; }
//  SECTION2: These produce compiler warning: reference to temporary, and use gives seg fault
const std::string &getSref() { return getS(); }
const std::string_view &getSVrefFromTemp() { return getS(); }
//  also produces compiler warning: reference to temporary, 
//      even though theString is not temporary
const std::string_view &getSVrefFromPerm() { return theString; }
//  SECTION3:  
std::string_view getSVfromPerm() { return theString; }  //  works fine
std::string_view getSVfromRef() { return getRef(); }    //  works fine
std::string_view getSVfromTemp() { return getS(); }     //  silent bug.
private:
std::string theString;
};
int main()
{
C1 myClass;
//  SECTION2: produces seg fault
//     std::cout << "getSref: "" << myClass.getSref() << ""." << std::endl;
//     std::cout << "getSVrefFromTemp: "" << myClass.getSVrefFromTemp() << ""." << std::endl;
//     std::cout << "getSVrefFromPerm: "" << myClass.getSVrefFromPerm() << ""." << std::endl;
//  SECTION3:  These compile silently.
//  works fine
std::cout << "getSVfromPerm: "" << myClass.getSVfromPerm() << ""." << std::endl;
//  works fine
std::cout << "getSVfromRef: "" << myClass.getSVfromRef() << ""." << std::endl;
//  silent bug prints garbage
std::cout << "getSVfromTemp: "" << myClass.getSVfromTemp() << ""." << std::endl;
}

有没有办法在从临时返回按值string_view时获得编译器警告?

有!使用叮当 10。对于此计划:

#include <string>
#include <string_view>
struct C
{
std::string getS();
std::string_view getSVfromTemp() { return getS(); }
};

叮当-10 发射:

<source>:7:47: warning: returning address of local temporary object [-Wreturn-stack-address]
std::string_view getSVfromTemp() { return getS(); }    
^~~~~~