整数和双精度变量的初始化

Initialization of int and double variables

本文关键字:初始化 变量 双精度 整数      更新时间:2023-10-16

我有以下C++代码:

#include <iostream>
using namespace std;
#include <stdio.h>

int main (int argc , char ** argv) 
{
int i1;
int i2;
double d1;
double d2;
printf("i1: %d, i2: %d, d1: %f, d2: %f n", i1, i2, d1, d2);
}

输出为

i1:4195872、i2:0、d1:0.000000、d2:0.000000

每次运行程序时,我都会得到相同的输出。现在假设我使用以下代码:

#include <iostream>
using namespace std;
#include <stdio.h>

int main (int argc , char ** argv) 
{
int i1;
int i2;
double d1;
double d2;
cout << "i1: " << i1;
cout << " i2: " << i2;
cout << " d1: " << d1;
cout << " d2: " << d2;
}

现在我得到以下输出:

i1:4196144 i2:0 d1:6.95294e-310 d2:0

当我重新运行程序时,d1 的值略有变化,其他值保持不变。

为什么以这种方式初始化值?为什么没有随机初始化或初始化为零?

为什么以

这种方式初始化值?

基本类型和自动存储持续时间的默认初始化变量具有不确定的值。

为什么没有随机初始化或初始化为零?

因为标准没有这么说,编译器实现者选择不这样做。随机化和零初始化都可能比不这样做慢,因此选择似乎是合乎逻辑的。

该标准所说的是,读取不确定的值具有未定义的行为(除了少数特定情况,请参阅标准报价)。

当前标准草案:

[dcl.init] (12)如果未为对象指定初始值设定项,则默认初始化该对象。获取具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,如果未对对象执行初始化,则该对象将保留不确定值,直到替换该值 ([expr.ass])。[ 注意:具有静态或线程存储持续时间的对象初始化为零,请参阅 [basic.start.static]。 — 尾注 ] 如果计算产生了不确定的值,则除以下情况外,该行为是未定义的:

  • (12.1) 如果通过计算以下条件产生无符号窄字符类型或 std::byte 类型 ([cstddef.syn]) 的不确定值:

    • (12.1.1) 条件表达式的第二个或第三个操作数,
    • (12.1.2) 逗号表达式的右操作数,
    • (12.1.3) 将强制转换或转换([conv.integral]、[expr.type.conv]、[expr.static.cast]、[expr.cast])转换为无符号窄字符类型或 std::byte 类型 ([cstddef.syn]),或
    • (12.1.4) 丢弃值表达式,

    则操作的结果是一个不确定的值。

  • (12.2) 如果无符号窄字符类型或 std::byte 类型的不确定值是通过计算简单赋值运算符
  • 的右操作数产生的,该简单赋值运算符的第一个操作数是无符号窄字符类型或 std::byte 类型的左操作数的左键值,则不确定值将替换左操作数引用的对象的值。
  • (12.3) 如果在初始化无符号窄字符类型的对象时,初始化表达式的计算产生了无符号窄字符类型的不确定值,则该对象将初始化为不确定值。
  • (12.4) 如果在初始化 std::byte 类型的对象时,初始化表达式的计算产生了无符号窄字符类型或 std::byte 类型的不确定值,则该对象将初始化为不确定值。

你的程序有未定义的行为,这意味着你得到的输出是完全随机的(事实上你得到的输出

就是这样)。在C++中,非类类型的局部变量不会自动初始化。读取未初始化变量的值是未定义的。

这是未定义的行为,因为未初始化的变量保存垃圾值。

如果不初始化函数中定义的变量, 变量值仍未定义。这意味着元素承担 以前驻留在内存中该位置的任何值。

参考 cpp首选项。