是C#未初始化变量的危险吗? [英] Are C# uninitalized variables dangerous?

查看:269
本文介绍了是C#未初始化变量的危险吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉C#规范, 5.3节它说,一个变量必须在使用前进行分配。

在C和非托管C ++这是有道理的堆栈不被清除,并用一个指针的内存位置可以在任何地方(导致难以追查错误)。

但我的IM pression,有没有真正的未分配值由运行时允许的。尤其是未初始化的引用类型将永远有一个空值,永远不会从方法或随机值的previous调用遗留下来的价值。

这是正确的,还是我被错误地假定为空的检查就足够了,这些年?你能真实地已经在unintialized C#中的变量,还是在CLR照顾这一点,总是有一些设置值。


解决方案

  

我是IM pression,有没有真正运行时允许的未分配的价值观之下。尤其是未初始化的引用类型将永远有一个空值,永远不会从方法或随机值的previous调用遗留下来的价值。 这是正确的?


我注意到,实际上没有人回答了你的问题呢。

这个问题的答案,你居然问的问题是八九不离十。

正如其他人所指出的,一些变量(数组元素,字段等)被列为自动被最初分配的默认值。 (这是空的引用类型,零数字类型,假的布尔变量,并为用户自定义的结构自然递归)。

一些变量是不属于初始分配;特别是局部变量没有最初分配。他们必须被编译器列为明确赋值,在他们那里的的使用所有的点。

您的问题则实际上是是被归类为的不明确赋值的实际初始分配一个局部变量的同样的方式,一个字段会是什么?而这个问题的答案是,在实践中,最初运行时都分配当地人。

这有几个不错的性能。首先,你可以在调试器中观察他们在其默认状态他们的第一项任务之前。第二,有没有机会,垃圾收集器会被欺骗提领坏指针,只是因为有垃圾离开了那个现在被视为管理的参考堆栈。等等。

运行时是的允许的离开当地人任何垃圾恰巧有初始状态,如果它可以安全地这样做。但作为一个实现细节,它没有以往任何时候都选择这样做。它零出为一个局部变量积极的存储器。

有关,当地人必须在使用之前被明确赋值规则的原因则是观察当地的垃圾未初始化状态的的以prevent你。这已经是不可观察的,因为CLR积极清除本地人为默认值,同样因为它的字段和数组元素。 的原因,这是在C#违法是因为使用一个未分配的地方有被一个bug高的可能性。:我们根本是非法,然后从曾经有这样一个错误的编译器prevents你。

I'm familiar with the C# spec, section 5.3 which says that a variable has to be assigned before use.

In C and unmanaged C++ this makes sense as the stack isn't cleared and the memory location used for a pointer could be anywhere (leading to hard to track down bug).

But I am under the impression that there are not truly "unassigned" values allowed by the runtime. In particular that a reference type that is not initialized will always have a null value, never the value left over from a previous invocation of the method or random value.

Is this correct, or have I been mistakenly assuming that a check for null is sufficient all these years? Can you have trully unintialized variables in C#, or does the CLR take care of this and there's always SOME value set.

解决方案

I am under the impression that there are not truly "unassigned" values allowed by the runtime. In particular that a reference type that is not initialized will always have a null value, never the value left over from a previous invocation of the method or random value. Is this correct?

I note that no one has actually answered your question yet.

The answer to the question you actually asked is "sorta".

As others have noted, some variables (array elements, fields, and so on) are classified as being automatically "initially assigned" to their default value. (Which is null for reference types, zero for numeric types, false for bools, and the natural recursion for user-defined structs).

Some variables are not classified as initially assigned; local variables in particular are not initially assigned. They must be classified by the compiler as "definitely assigned" at all points where their values are used.

Your question then is actually "is a local variable that is classified as not definitely assigned actually initially assigned the same way that a field would be?" And the answer to that question is yes, in practice, the runtime initially assigns all locals.

This has several nice properties. First, you can observe them in the debugger to be in their default state before their first assignment. Second, there is no chance that the garbage collector will be tricked into dereferencing a bad pointer just because there was garbage left on the stack that is now being treated as a managed reference. And so on.

The runtime is permitted to leave the initial state of locals as whatever garbage happened to be there if it can do so safely. But as an implementation detail, it does not ever choose to do so. It zeros out the memory for a local variable aggressively.

The reason then for the rule that locals must be definitely assigned before they are used is not to prevent you from observing the garbage uninitialized state of the local. That is already unobservable because the CLR aggressively clears locals to their default values, the same as it does for fields and array elements. The reason this is illegal in C# is because using an unassigned local has high likelihood of being a bug. We simply make it illegal, and then the compiler prevents you from ever having such a bug.

这篇关于是C#未初始化变量的危险吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆