Здравствуйте, Serginio1, Вы писали:
S> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????
Здравствуйте, Alexey Shirshov, Вы писали:
AS>Кто угадает какой будет вывод?
А вот интересная вешчь ( в MS ньюсгруппе по дотнету подсказали)
Обратите внимание на выделение жирным шрифтом.
Так что, читаем докумнтацию
Visual Basic Language Specification
8.3 Local Declaration Statements
A local declaration statement declares a new local variable. Its syntax is the same as a variable or constant declaration, except that a local variable declaration must always specify a modifier.
There are three kinds of locals. Regular locals are declared using the Dim modifier. Constant locals are equivalent to type-member constants and are specified with the Const modifier. Static locals are locals that retain their value across invocations of the method; static locals are declared using the Static modifier. Static locals declared within nonshared methods are per instance: each instance of the type that contains the method has its own copy of the Static local. Static locals declared within Shared methods are per type; there is only one copy of the Static local for all instances.
Variable initializers on locals are equivalent to assignment statements placed at the textual location of the declaration. Thus, if execution branches over the local declaration, the variable initializer will not be executed. If the local declaration is executed more than once, the variable initializer will be executed an equal number of times. It is important to note that locals are only initialized to their type's default value once, upon entry into the method.
Local variables are scoped to the statement block in which they are declared.
Здравствуйте, AndrewVK, Вы писали:
S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ???? AVK>Дергается стек
А как джит узнает, что надо дергать стек, если в мсиле все переменные объявляются в начале метода?
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Tom, Вы писали: Tom>>Lexey был абсолютно прав. Таким образом обьявлять переменные абсолютно нормальная практика. Применятся в тех случаях когда переменная/обьект должна быть создана на каждой итерации цикла.
S> Не могли бы вы объяснить что будет происходить при объявление переменных Value типа. S> Для объектов понятно выделяется память в куче, сборщик мусора пусть работает. S> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????
Ваш вопрос на самом деле очень интересный. На сях память в стеке для локальных переменных выделяется только один раз при входе в функцию. Думаю тоже происходит и в CLR. Постоянно изменять размер стека на мой взгляд не возможно да и не нужно ак как расположение переменных в стеке зараннее не известно. Скорее всего CLR производит:
1) Выделение памяти один раз при входе в функцию для локальных переменных
2) Инициализацию этих локальных переменных (причём тут всё может зависеть от JIT компиляции/оптимизации). Например какой смысл в данном примере инициализировать переменную...
{
Int32 i;
i=1;
}
никакого. а вот в этом обязательно необходима инициализация
Int32 i;
Console.WriteLine(i);
i=1;
По этому я думаю инициализация производиться там, где решит это делать JIT компилятор, а память выделяется только один раз.
ЗЫ: Это конечно всё теория. Теперь пойду проверять
Здравствуйте, Tom, Вы писали:
Tom>Ваш вопрос на самом деле очень интересный. На сях память в стеке для локальных переменных выделяется только один раз при входе в функцию.
Не всегда, я бы даже сказал, что обычно не так.
При таком коде vc6,7 (может и более ранние) сгенерирует код, при котором буфер будет выделен только при заходе в if. Это вроде даже где-то в стандарте зафиксировано.
if (condition)
{
char buffer[10000];
}
зы
если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным
Здравствуйте, Alexey Shirshov, Вы писали:
AS>Кто угадает какой будет вывод?
А что тебе не нравится?
Все логично даже просто с точки зрения здравого смысла.
Переменную j ты не инициализируешь сам, поэтому в ней может находится произвольный мусор, то что этот мусор является предыдущим значением — это уже частности.
Здравствуйте, DarkGray, Вы писали:
DG>зы DG>если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным
VC обычно использует ebp-based frame. Смещения локальных переменных в этом случае не меняются.
Здравствуйте, DarkGray, Вы писали:
DG>Здравствуйте, Alexey Shirshov, Вы писали:
AS>>Кто угадает какой будет вывод?
DG>А что тебе не нравится? DG>Все логично даже просто с точки зрения здравого смысла. DG>Переменную j ты не инициализируешь сам, поэтому в ней может находится произвольный мусор, то что этот мусор является предыдущим значением — это уже частности.
Какой мусор?- по спецификации локальные переменные инициализируються значением по умолчанию.
Здравствуйте, DarkGray, Вы писали:
DG>Здравствуйте, Tom, Вы писали:
Tom>>Ваш вопрос на самом деле очень интересный. На сях память в стеке для локальных переменных выделяется только один раз при входе в функцию.
DG>Не всегда, я бы даже сказал, что обычно не так.
DG>При таком коде vc6,7 (может и более ранние) сгенерирует код, при котором буфер будет выделен только при заходе в if. Это вроде даже где-то в стандарте зафиксировано. DG>
DG>зы DG>если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным
Здравствуйте, DarkGray, Вы писали:
AS>>>Нет идей. Почему?
>> "Оптимизация", блин.
DG>Попробуй добавить в define фигурные скобки — #define {bla-bla} или добавить if — #define if(true){bla-bla}
Если внимательно посмотришь, скобки у меня там изначально были. Без них это бы просто не компилировалось. Не думаю, что if (true) тоже бы что-то дало. Компилятор не дурак — такие if-ы должен выбрасывать сразу. Я проблему решил, добавив макрос
#define USES_DEBUG() WCHAR __buf_[1024];
и вынеся таким образом объявление буфера в начало метода.
Но радости от этого совсем никакой. Смахивает на явный баг оптимизатора.
Здравствуйте, AndrewVK, Вы писали:
AVK>Это точно? Что то я нигде такого не встречал.
По спецификации VB.Net:
Dim Statement
...
If you do not specify an initialization value for a variable, Visual Basic initializes it to the default value for its data type. The default initialization values are as follows:
0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a separate variable.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????
AVK>Дергается стек
Тогда непонятно, почему на данном форуме защищается объявление переменных в цикле.
Или это корпоративный стиль программирования.
Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???
В предыдущем вопросе допустил неточность, так как под саму ссылку тоже нужно выделять место в стеке.
Извиняюсь за глупые вопросы, т.к. в Паскале таких ситуаций не возникает.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????
AVK>Дергается стек
Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.
Здравствуйте, migel, Вы писали:
AVK>>Дергается стек M>Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.
Вот именно что максимальный. А всякие Ldxxx и Stxxx никто не отменял
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, migel, Вы писали:
AVK>>>Дергается стек M>>Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.
AVK>Вот именно что максимальный. А всякие Ldxxx и Stxxx никто не отменял
ну дык память то не перераспределяется... да и на стэке объекты не создаються а просто грузятся через ldloc...
Как болеется?