不知道某个东西是否被忽略会引入未定义的行为吗
Can not knowing whether something is elided introduce undefined behavior?
假设我们有一个结构,它有一个成员指针,该指针有条件地指向内部数组或堆上的某个位置,如下所示:
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总是未定义的行为吗?它是否是未定义的行为(比如它是否决定消除(取决于编译器吗?还是定义明确的行为?(同样的问题也可能适用于第一个例子(
在所有不强制执行复制省略的情况下,执行以下操作时会出现未定义的行为:
auto ex = ...
ex.data[0] = 'h';
std::cout << ex.p[0];
从c++17开始,此函数:
Ex f1() {return Ex();}
保证执行复制省略,因此如果ex
是f1()
的结果,则上面的代码是可以的。
一般来说,我建议不要依赖于此,只需为类提供正确的复制构造函数即可避免此类问题。
相关文章:
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 此增量后语句是否会导致未定义的行为?
- Windows 链接器是否使用 LoadLibrary 解析 DLL 中未定义的符号?
- 如何测试 size_t -1 是否未定义,其中 size_t 为 0?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 负指数是否必然意味着未定义的行为
- 在"printf"中使用标签"h"或"hh"是否涉及未定义的
- 在 C++17 中,是否未定义使用无锁原子学保护从信号处理程序传递的数据?
- C++ 如何检查 char 变量是否未定义(未初始化)
- 递减 std::vector::begin 是否未定义,即使它从未被使用过?
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 在C++中,转换为simd类型是否有未定义的行为
- 是否是从等待返回到悬而未决的"this"实例的未定义行为?
- 是否未定义将对函数范围变量的引用作为值返回
- FBString 的小字符串优化是否依赖于未定义的行为?
- 移动 std::bitset<N> 是否超过 N 个位置未定义的行为?
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 使用c_str是否有未定义的异常行为
- i=i++;未定义.是否i=foo(i++)也未定义