写入未初始化的变量:未定义的行为?
Write to uninitialized variable: undefined behaviour?
在 Bjarne Stroustrup 的 "A Tour of C++"(第二版)的第 18 页,他说 "for almost all types, the effect of reading from or writing to an uninitialized variable is undefined"。
我明白为什么读取一个未初始化的变量是未定义的行为,但为什么写入一个未初始化的变量是未定义的行为?当然我错过了一些东西,因为否则做 int x;
之类的事情是完全没用的,因为你不能读取或写入 x
(即不能用 x
做任何事情)而不触发未定义的行为(假设int
是适用于此的 "almost all types" 之一。
写入未初始化的变量是可以的。唯一一次出现未初始化变量的未定义行为是在向它们写入任何内容之前尝试读取它们。那么你有未定义的行为,因为它具有的值是未定义的。
现在未定义的行为是写入一个生命周期尚未开始的对象。例如,如果你有一个像
这样的结构
struct foo
{
std::string str;
};
你用malloc
像
为它获取记忆
foo* f = malloc(sizeof(foo));
那你做不到
f->str = "some text";
这是因为 malloc
实际上并没有给你一个对象。它所做的只是为对象分配存储空间,这不足以认为您实际上拥有一个对象,因为 std::string
有一个非平凡的构造函数,这意味着 foo
的构造函数也是非平凡的。为了启动 *f
的生命周期,您需要调用 foo
的构造函数。为此,您使用 placement new 它将在您提供给它的内存中构造对象。那看起来像
foo* f = malloc(sizeof(foo));
new(f) foo;
这很可能是 Bjarne 试图谈论的内容。
在 Bjarne Stroustrup 的 "A Tour of C++"(第二版)的第 18 页,他说 "for almost all types, the effect of reading from or writing to an uninitialized variable is undefined"。
我明白为什么读取一个未初始化的变量是未定义的行为,但为什么写入一个未初始化的变量是未定义的行为?当然我错过了一些东西,因为否则做 int x;
之类的事情是完全没用的,因为你不能读取或写入 x
(即不能用 x
做任何事情)而不触发未定义的行为(假设int
是适用于此的 "almost all types" 之一。
写入未初始化的变量是可以的。唯一一次出现未初始化变量的未定义行为是在向它们写入任何内容之前尝试读取它们。那么你有未定义的行为,因为它具有的值是未定义的。
现在未定义的行为是写入一个生命周期尚未开始的对象。例如,如果你有一个像
这样的结构struct foo
{
std::string str;
};
你用malloc
像
foo* f = malloc(sizeof(foo));
那你做不到
f->str = "some text";
这是因为 malloc
实际上并没有给你一个对象。它所做的只是为对象分配存储空间,这不足以认为您实际上拥有一个对象,因为 std::string
有一个非平凡的构造函数,这意味着 foo
的构造函数也是非平凡的。为了启动 *f
的生命周期,您需要调用 foo
的构造函数。为此,您使用 placement new 它将在您提供给它的内存中构造对象。那看起来像
foo* f = malloc(sizeof(foo));
new(f) foo;
这很可能是 Bjarne 试图谈论的内容。