且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

初始化 int 影响函数返回值

更新时间:2022-12-16 08:57:45

与所有非static 存储持续时间的基本类型一样,声明但不定义int 不会导致默认初始化.它使变量未初始化.这并不 not 意味着 i 只保存一个随机值.它包含no(已知的、有效的)值,因此您还不能读取它.

Like all basic types of non-static storage duration, declaring but not defining an int does not cause default initialisation. It leaves the variable uninitialised. That does not mean i just holds a random value. It holds no (known, valid) value, and therefore you're not allowed to read it yet.

这是来自 C++11 标准的相关引用,来自评论中的 Angew.这不是一个新的限制,从那时起也没有改变:

Here's the relevant quote from the C++11 Standard, via Angew in the comments. This wasn't a new restriction, nor has it changed since then:

C++11 4.1/1,谈论左值到右值的转换(基本上是读取变量的值):如果泛左值所指的对象......未初始化,则需要这种转换的程序具有未定义的行为."

C++11 4.1/1, talking about an lvalue-to-rvalue conversion (basically reading a variable's value): "If the object to which the glvalue refers is ... uninitialized, a program that necessitates this conversion has undefined behavior."

对未初始化变量的任何读取都会导致未定义的行为,因此任何事情都可能发生.与您的程序使用一些未知的默认值继续按预期运行不同,编译器可以让它做任何事情,因为行为是未定义的,并且标准没有要求在这种情况下应该发生什么.

Any read of an unitialised variable causes undefined behaviour, and so anything can happen. Rather than your program continuing to function as expected using some unknown default value, compilers can make it do absolutely anything, because the behaviour is undefined, and the Standard imposes no requirements on what should happen in such a scenario.

实际上,这通常意味着优化编译器可能会简单地删除任何以任何方式依赖 UB 的代码.没有办法对做什么做出正确的决定,所以决定什么都不做是完全有效的(这恰好也是对大小和速度的优化).或者正如评论者所提到的,它可能会保留代码,但替换尝试读取 i 与最接近的无关值,或者在不同的语句中使用不同的常量,等等.

In practical terms, that usually means an optimising compiler might simply remove any code that relies in any way on UB. There's no way to make a correct decision about what to do, so it's perfectly valid to decide to do nothing (which just happens also to be an optimisation for size and often speed). Or as commenters have mentioned, it might keep the code but replace attempts to read i with the nearest unrelated value to hand, or with different constants in different statements, or etc.

打印变量并不像您想象的那样算作检查它",因此没有区别.没有办法检查"一个未初始化的变量,从而使自己接种 UB.读取变量的行为只有在程序已经向其写入特定值时才定义.

Printing a variable doesn't count as 'checking it' as you think, so that makes no difference. There is no way to 'check' an uninitialised variable and thereby to inoculate yourself against UB. The behaviour of reading the variable is only defined if the program has already written a specific value to it.

我们没有必要推测为什么会出现特定的任意类型的 UB:您只需要修复您的代码,使其确定性地运行.

There is no point in us speculating on why particular arbitrary types of UB occur: you just need to fix your code so that it operates deterministically.

你为什么要使用它未初始化呢?这只是学术"吗?

Why do you want to use it uninitialised anyway? Is this just 'academic'?