繁体   English   中英

Visual Studio Debugger Voodoo

[英]Visual Studio Debugger Voodoo

好吧,也许这并不是那么神奇,因为我真的不了解调试器的工作原理,更不用说编辑和继续了,这真是太棒了。

但我想知道是否有人知道调试器在这种情况下使用变量声明做了什么。 我可以通过我的代码调试,提前执行行 - 通过变量初始声明和赋值,代码仍然运行正常。 如果它是一个值类型,它将具有它的默认值,对于ref类型,为null。

因此,如果我创建一个在声明它之前使用变量的函数它将无法编译,但如果我使用调试器以这种方式运行它,它仍将运行而不会出错。 为什么是这样? 这是否与您不能在声明中设置断点有关?

是的,这些声明更具结构性。 它们是在调用方法时分配的堆栈中的本地成员的一部分。 你不能打破它们,因为它们并没有真正发生在你写它们的地方 - 它们不是指令。

编译器在声明之前不会让你使用它们的原因主要是为了你的理智 - 你总是知道要查找声明。 方法中变量的复杂范围将进一步说明这一点。

根据文章通过不初始化变量获得性能

在.NET中,公共语言运行时(CLR)在创建所有变量后立即初始化它们。 值类型初始化为0,引用类型初始化为null。

据推测,调试器已经知道这些变量,因为代码已经被编译,或者(现在我不太可能输入它,但是)调试器足够聪明,可以检测到声明了变量。

我认为,因为您正在使用调试器,您会混淆两个不同的活动,编译和执行,以及两种不同的语句类型,声明性和功能性。

编译时,声明性语句告诉编译器为变量保留一些内存。 它说“哦,你想要声明一个名为”wombatCount“的整数”;好吧,我将获取地址0x1234并为你保留四个字节,并在它们上贴上一个名为wombatCount的标签。“ 这在编译期间发生,远在您运行代码之前。 *

当您在调试器中执行代码时,您正在运行代码,因此它已经知道它为您保留的每个内存字节。 变量wombatCount已经与地址0x1234处的四个字节相关联,因此它可以随时立即访问和更改该数据,而不仅仅是在声明语句之后。 当然,你的程序不能,但调试器可以。

C#语言语法要求您在代码中使用它之前声明内存,但这只是语言定义的一部分,而不是所有编译器的硬性要求。 有些语言根本不需要你预先声明你的变量,甚至有些古老的语言可以在代码中的任何一点声明变量,而不仅仅是你将使用它们的“上方”。 但是语言开发人员现在明白语言语法对于人类理解是最重要的,并且不再是为了便于机器编码或帮助编译器编写者,因此通常创建现代语言语法以尽可能地帮助程序员。 这意味着让事情变得不那么混乱,因此“声明必须先行”是帮助您避免错误的常见规则。

(*为了在技术上更正确,我相信在.Net中,标签只在编译时与一个指针列表相关联,这些指针将在运行时保留内存,但数据字节在您使用之前不会实际分配。是内部的,对你的理解不是很重要。重要的是,声明性声明在编译期间提前声明标签。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM