假设我们有一个结构体,其中有一个指针成员,根据条件可能会指向内部数组或堆上的某个位置,如下所示:
由于拷贝省略的原因,以下代码将会输出 "h":
据我所知,这个函数可能被省略,但如果没有省略,以下代码将会产生未定义行为:
我的问题是,示例2是否总是未定义的行为?编译器是否决定它是否未定义行为(例如是否决定省略)?还是说这是明确定义的行为?(同样的问题可能也适用于第一个示例)
struct Ex {
char* p;
char data[14];
bool is_heap;
Ex() : p(&data[0]), data(), is_heap(false) {}
//etc...
};
现在考虑这个函数
Ex f1() {return Ex();}
由于拷贝省略的原因,以下代码将会输出 "h":
int main() {
auto ex = f1();
ex.data[0] = 'h';
std::cout << ex.p[0];
}
但请考虑以下函数
Ex f2() {
auto ret = Ex();
return ret;
}
据我所知,这个函数可能被省略,但如果没有省略,以下代码将会产生未定义行为:
int main() {
auto ex = f2();
ex.data[0] = 'h';
std::cout << ex.p[0]; // maybe derefrencing dangling pointer, maybe printing out "h"?
}
我的问题是,示例2是否总是未定义的行为?编译器是否决定它是否未定义行为(例如是否决定省略)?还是说这是明确定义的行为?(同样的问题可能也适用于第一个示例)
char* p;
改为char* const p;
,这样就可以防止出现问题。 - Eljay