gpt4 book ai didi

c++ - 如何检测对临时对象成员的引用

转载 作者:可可西里 更新时间:2023-11-01 16:43:04 25 4
gpt4 key购买 nike

我的同事最近在 Windows 中编译了我们的程序,发现了一个错误:

  std::string a = "hello "; 
std::string b = "world";
const char *p = (a+b).c_str();
printf("%s\n", p);

出于某种原因,它没有在我们的 Linux 可执行文件中崩溃。

我们的编译器都没有给出任何类型的警告,所以我们现在担心代码中可能存在这个错误。

虽然我们可以 grep 查找 c_str() 的出现并进行目视检查,但也有可能有人还做了以下操作:

struct I {
int num;
I() { num=0; }
};

struct X {
I *m;
X() { m = new I; }
~X() { delete m; }
I get() { return *m; } // version 1, or
I& get() { return *m; } // version 2
};

并像这样访问它:

  I& a = X().get();         // will get a reference to a temporary, or a valid copy?
cout << a.num;

代替:

 cout << X().get().num;   

哪个是安全的(不是吗?)

问题有什么方法可以捕获此类错误(可能使用编译器,甚至是断言)?
我需要确保如果 struct X 的作者在 version 12 之间更改 get()程序将警告错误

最佳答案

简单的回答:通常你无法捕获这些错误,原因是有类似的结构可能非常好,所以编译器必须知道所有函数的语义才能警告你。

在更简单的情况下,比如获取临时地址,许多编译器已经警告过你,但在一般情况下,编译器即使不是不可能也很难知道。

对于 .c_str() 的一些类似示例,请考虑:

std::vector< const char * > v;
v.push_back( "Hi" );
const char* p = *v.begin();

begin 的调用返回一个临时值,类似于表达式 (a+b),并且您正在调用该临时值的成员函数(运算符*) 返回一个 const char*,这与您的原始案例非常相似(从所涉及的类型的角度来看)。问题是,在这种情况下,指针在调用后仍然有效,而在您的 (.c_str()) 中则不是,但它是操作语义的一部分,而不是编译器可以为您检查的语法。 .get() 示例也是如此,编译器不知道返回的引用是否指向在表达式之后有效的对象。

所有这些都属于未定义行为的范畴。

关于c++ - 如何检测对临时对象成员的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8315246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com