从临时文件返回按值 string_view 时,有没有办法获得编译器警告?
Is there a way to get a compiler warning when returning a by-value string_view from a temporary?
我一直在通过将它们应用于一些旧代码来学习 c++17 的变化,并发现 returning std::string_view
会产生无声的错误,在我看来,对临时编译器警告是合适的。有没有办法生成一个?
我正在使用 g++ 9.3.0,带有编译器标志 -ggdb -Wall -std=c++17
。我也试过 clang 和 clang-tidy/clazy 没有警告。
首先,我最近了解到,最好只使用 std::string_view
来替换参数中的 const std::string &
,而不是作为 return 值。 This article 向我解释得很好。不幸的是,我并没有看到它通常以这种方式呈现,所以我想知道其他人是否也有同样的问题。
(下面代码中的第 1 部分)
我知道尝试 return 对临时字符串的非常量引用不会编译。无论该引用是 std::string &
还是 std::string_view &
,都一样。
如果我尝试 return 对永久字符串 theString
.
的非常量 std::string_view &
引用,则会发生相同的编译器错误
(下面代码中的第 2 部分)
我也知道,如果我尝试 return 对临时字符串的 const 引用,它会编译,但编译器会发出警告,指出我 return 编辑了对临时字符串的引用。与第 1 节一样,无论该引用是 const std::string &
还是 const std::string_view &
.
都是如此
与第 1 部分一样,如果我尝试 return 对永久字符串 theString
.
的 const std::string_view &
引用,则会出现对临时编译器警告的相同引用
(下面代码中的第 3 部分)
如果我尝试 return 从永久的 std::string_view
或从对永久的引用,它工作正常,当然,但如果我尝试 return 从临时的,它编译没有警告,但它的使用会产生垃圾。
编译器不应该产生与代码第 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;
}
Is there a way to get a compiler warning when returning a by-value string_view
from a temporary?
有!使用 clang 10。对于此程序:
#include <string>
#include <string_view>
struct C
{
std::string getS();
std::string_view getSVfromTemp() { return getS(); }
};
clang-10 发出:
<source>:7:47: warning: returning address of local temporary object [-Wreturn-stack-address]
std::string_view getSVfromTemp() { return getS(); }
^~~~~~
我一直在通过将它们应用于一些旧代码来学习 c++17 的变化,并发现 returning std::string_view
会产生无声的错误,在我看来,对临时编译器警告是合适的。有没有办法生成一个?
我正在使用 g++ 9.3.0,带有编译器标志 -ggdb -Wall -std=c++17
。我也试过 clang 和 clang-tidy/clazy 没有警告。
首先,我最近了解到,最好只使用 std::string_view
来替换参数中的 const std::string &
,而不是作为 return 值。 This article 向我解释得很好。不幸的是,我并没有看到它通常以这种方式呈现,所以我想知道其他人是否也有同样的问题。
(下面代码中的第 1 部分)
我知道尝试 return 对临时字符串的非常量引用不会编译。无论该引用是 std::string &
还是 std::string_view &
,都一样。
如果我尝试 return 对永久字符串 theString
.
std::string_view &
引用,则会发生相同的编译器错误
(下面代码中的第 2 部分)
我也知道,如果我尝试 return 对临时字符串的 const 引用,它会编译,但编译器会发出警告,指出我 return 编辑了对临时字符串的引用。与第 1 节一样,无论该引用是 const std::string &
还是 const std::string_view &
.
与第 1 部分一样,如果我尝试 return 对永久字符串 theString
.
const std::string_view &
引用,则会出现对临时编译器警告的相同引用
(下面代码中的第 3 部分)
如果我尝试 return 从永久的 std::string_view
或从对永久的引用,它工作正常,当然,但如果我尝试 return 从临时的,它编译没有警告,但它的使用会产生垃圾。
编译器不应该产生与代码第 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;
}
Is there a way to get a compiler warning when returning a by-value
string_view
from a temporary?
有!使用 clang 10。对于此程序:
#include <string>
#include <string_view>
struct C
{
std::string getS();
std::string_view getSVfromTemp() { return getS(); }
};
clang-10 发出:
<source>:7:47: warning: returning address of local temporary object [-Wreturn-stack-address]
std::string_view getSVfromTemp() { return getS(); }
^~~~~~