Visual Studio Debugger Voodoo - PullRequest
3 голосов
/ 14 мая 2010

Хорошо, возможно, это не так удивительно, учитывая, что я не совсем понимаю, как работает отладчик, не говоря уже о Редактировании и продолжении, что совершенно потрясающе.

Но мне было интересно, знает ли кто-нибудь, что делает отладчик с объявлениями переменных в этом сценарии. Я могу отлаживать свой код, перемещать строку выполнения вперед - после первоначального объявления и назначения переменных, и код все еще работает нормально. Если это тип значения, он будет иметь значение по умолчанию, для типа ссылки - ноль.

Так что, если я создам функцию, которая использует переменную до того, как она объявлена, она не скомпилируется, но если я использую отладчик для ее запуска таким образом, она все равно будет работать без ошибок. Почему это? И связано ли это с тем, что вы не можете поставить точку останова в объявлении?

Ответы [ 3 ]

4 голосов
/ 14 мая 2010

Да, эти декларации являются более структурными. Они являются частью локальных элементов в стеке, которые выделяются при вызове метода. Вы не можете сломать их, потому что они на самом деле не происходят там, где вы их пишете - это не инструкции.

Причина, по которой компилятор не позволит вам использовать их до того, как они будут объявлены, в основном для вашего здравого смысла - вы всегда знаете, как найти объявление. Сложная область видимости переменных внутри метода дополнительно проиллюстрирует эту точку.

1 голос
/ 18 мая 2010

Я думаю, что, поскольку вы используете отладчик, вы путаете два разных действия, скомпилировать и выполнить, и два разных типа операторов, декларативный и функциональный.

Когда вы компилируете, декларативный оператор говорит компилятору зарезервировать часть памяти для вашей переменной. Он говорит: «О, вы хотите объявить целое число с именем« wombatCount »; хорошо, я возьму адрес 0x1234 и зарезервирую четыре байта только для вас и наклею на них метку с именем wombatCount». Это происходит во время компиляции задолго до того, как вы запустите свой код. *

Когда вы выполняете код в отладчике, вы запускаете свой код, поэтому он уже знает о каждом байте памяти, зарезервированном для вас. Переменная wombatCount уже связана с четырьмя байтами по адресу 0x1234, поэтому она может немедленно получить доступ и изменить эти данные в любое время, а не только после вашего объявления объявления. Ваша программа не может, конечно, но отладчик может.

Синтаксис языка C # требует, чтобы вы объявляли память перед использованием ее в своем коде, но это только часть определения языка, а не жесткое требование всех компиляторов. Существуют языки, которые вообще не требуют предварительного объявления ваших переменных, и есть даже некоторые древние языки, где вы можете объявлять переменные в любой точке кода, а не только «выше», где вы будете их использовать. Но разработчики языка теперь понимают, что синтаксис языка наиболее важен для понимания человеком и больше не для простоты машинного кодирования или помощи составителям компиляторов, поэтому современные синтаксисы языка обычно создаются, чтобы максимально помочь программистам. Это означает, что все должно быть менее запутанным, поэтому «объявления должны стоять на первом месте» - это общее правило, помогающее вам избежать ошибок.

(* Чтобы быть технически более точным, я считаю, что в .Net метки ассоциируются только во время компиляции со списком указателей, которые будут резервировать память во время выполнения, но байты данных фактически не выделяются, пока вы их не используете Разница внутренняя и не очень важна для вашего понимания. Важным выводом является то, что декларативный оператор объявляет метку заранее, во время компиляции.)

1 голос
/ 14 мая 2010

Согласно статье Повышение производительности без инициализации переменных :

В .NET Common Language Runtime (CLR) явно инициализирует все переменные, как только они создаются,Типы значений инициализируются равными 0, а ссылочные типы - нулем.

Предположительно, отладчик уже знает об этих переменных либо потому, что код уже скомпилирован, либо (кажется менее вероятным сейчас, когда я его печатаю, но) отладчик достаточно умен, чтобы обнаружить, что переменная была объявлена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...