簡體   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