当我在 C++ 中打印未初始化的变量时会发生什么?

发布于 2025-01-15 19:18:40 字数 181 浏览 3 评论 0原文

为什么会打印 32767 (或其他一些随机数)?什么是 std::cout 打印?为什么它不是NULL(或0)?

int main() 
{
    int a;
    std::cout << a;
}

Why does this print 32767 (or some other random number)? What is std::cout printing? Why is it not NULL (or 0)?

int main() 
{
    int a;
    std::cout << a;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独夜无伴 2025-01-22 19:18:40

这是因为在 C++ 中具有自动存储期限的变量不会自动初始化为零。在 C++ 中,您不需要为不需要的东西付费,并且自动初始化变量需要时间(将内存位置设置为零最终会减少机器指令,然后将其转换为控制物理位的电信号)。

该变量被保留在一个内存位置,而该内存位置恰好有一些垃圾。这些垃圾正在被 cout 打印出来。

正如@dwcanillas 所指出的,这是未定义的行为。相关:C 中声明的未初始化变量会发生什么情况?它有值吗?

来自 C++ 标准(强调我的):

8.5 初始化器 [dcl.init]

7) 默认初始化 T 类型的对象意味着

<块引用>

  • 如果 T 是(可能是 cv 限定的)类类型(第 9 条),则构造函数是
    经过考虑的。枚举了适用的构造函数(13.3.1.3),并且最好的构造函数
    初始化器 () 的一个是通过重载决议 (13.3) 选择的。这
    使用空参数列表调用如此选择的构造函数来初始化 >>对象。
  • 如果 T 是数组类型,则每个元素都会默认初始化。
  • 否则,不会执行初始化。

12) 如果没有为对象指定初始化程序,则该对象将被默认初始化。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果没有对该对象执行初始化,则该对象将保留不确定的值,直到该值被替换(5.18)。 [注意:具有静态或线程存储持续时间的对象是零初始化的,请参见 3.6.2。 — 尾注] 如果评估产生不确定值,则行为未定义,但以下情况除外:

<块引用>

——如果无符号窄字符类型(3.9.1)的不确定值是通过以下计算产生的:

——条件表达式的第二个或第三个操作数 (5.16),

——逗号表达式的右操作数 (5.19),

— 强制转换或转换为无符号窄字符类型(4.7、5.2.3、5.2.9、5.4)的操作数,或

——丢弃值表达式(第 5 条)

...

That is because variables with automatic storage duration are not automatically initialized to zero in C++. In C++, you don't pay for what you don't need, and automatically initializing a variable takes time (setting to zero a memory location ultimately reduces to machine intruction(s) which are then translated to electrical signals that control the physical bits).

The variable is being reserved a memory location, and it happens that some junk is at that memory location. That junk is being printed out by cout.

As pointed out by @dwcanillas, it is undefined behaviour. Related: What happens to a declared, uninitialized variable in C? Does it have a value?

From the C++ standard (emphasize mine):

8.5 Initializers [dcl.init]

7) To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type (Clause 9), constructors are
    considered. The applicable constructors are enumerated (13.3.1.3), and the best
    one for the initializer () is chosen through overload resolution (13.3). The
    constructor thus selected is called, with an empty argument list, to initialize >> the object.
  • If T is an array type, each element is default-initialized.
  • Otherwise, no initialization is performed.

12) If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.18). [Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

— If an indeterminate value of unsigned narrow character type (3.9.1) is produced by the evaluation of:

— the second or third operand of a conditional expression (5.16),

— the right operand of a comma expression (5.19),

— the operand of a cast or conversion to an unsigned narrow character type (4.7, 5.2.3, 5.2.9, 5.4), or

— a discarded-value expression (Clause 5)

...

眼眸里的那抹悲凉 2025-01-22 19:18:40

这是未定义的行为。您正在打印占用 a 内存的任何内容,在本例中恰好是 32767

It's undefined behavior. You are printing whatever occupies the memory of a, which in this case happens to be 32767.

当梦初醒 2025-01-22 19:18:40

C++14 (N3936) [dcl.init]/12 涵盖了该行为:

如果没有为对象指定初始化程序,则该对象将被默认初始化。当获取具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,并且如果没有对该对象执行初始化,则该对象将保留不确定值,直到该值被替换。

[...]如果计算产生不确定值,则行为未定义,但以下情况除外:

并且您的代码不包含在任何涵盖少数情况的“以下情况” 中允许传播 unsigned char 不确定值的情况。

The behaviour is covered by C++14 (N3936) [dcl.init]/12:

If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced.

[...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

and your code is not covered by any of the "following cases" which cover a few situations in which unsigned char indeterminate values are allowed to propagate.

清泪尽 2025-01-22 19:18:40

因为“a”不是全局/静态的。它是一个自动变量,在运行时进行初始化。如果它是全局的,则在编译时就会初始化为零。即:

• 静态变量在编译时初始化,因为它们的地址是已知且固定的。将它们初始化为 0 不会产生运行时成本。

• 自动变量对于不同的调用可以有不同的地址,并且必须在每次调用函数时在运行时初始化,从而产生可能不需要的运行时成本。如果您确实需要初始化,请请求它。

Because "a" is not global/static. Its an automatic variable for which initialization happens at run time. If it was global, initialization to zero would have happened at compile time. i.e

• static variables are initialized at compile-time, since their address is known and fixed. Initializing them to 0 does not incur a runtime cost.

• automatic variables can have different addresses for different calls and would have to be initialized at runtime each time the function is called, incurring a runtime cost that may not be needed. If you do need that initialization, then request it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文