Я фигею от VB.NET
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.07.03 10:30
Оценка: 1 (1) :)
Всем привет!

Не перестаю удивляться крутым парням из MS
        Dim ii As Integer = 0
        Do
            Dim j As Integer
            Console.WriteLine(j)
            j = 10
            ii += 1
        Loop While ii < 3

Кто угадает какой будет вывод?
Re: Я фигею от VB.NET
От: Gollum Россия  
Дата: 23.07.03 10:34
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?

0, 10, 10

?
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re: Я фигею от VB.NET
От: migel  
Дата: 23.07.03 10:34
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Всем привет!


AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?
Неужто
0
10
10
Re: Я фигею от VB.NET
От: Аноним  
Дата: 23.07.03 10:34
Оценка: +1
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Всем привет!


AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?

Не проверял, но думаю, что на консоль попадёт три нуля.
Re[2]: Я фигею от VB.NET
От: Gollum Россия  
Дата: 23.07.03 10:41
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Не проверял, но думаю, что на консоль попадёт три нуля.


А ведь да, кстати
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re: Я фигею от VB.NET
От: Ved Украина  
Дата: 23.07.03 10:42
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Кто угадает какой будет вывод?

Ну... по идее должен быть
0
0
0
... << RSDN@Home 1.0 beta 7 (MSSQL Edition) >>
Re[2]: Я фигею от VB.NET
От: Аноним  
Дата: 23.07.03 10:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не проверял, но думаю, что на консоль попадёт три нуля.


Проверено:

0
10
10
Re[2]: Я фигею от VB.NET
От: migel  
Дата: 23.07.03 10:49
Оценка:
Здравствуйте, Ved, Вы писали:
Ved>Ну... по идее должен быть
Ved>
Ved>0
Ved>0
Ved>0
Ved>

Это что получается у VB область активации локальной переменной ограничена методом но ни как ни блоком
"...поубывав бы гхадовь..."
Re[3]: Я фигею от VB.NET
От: Ved Украина  
Дата: 23.07.03 10:58
Оценка:
Здравствуйте, migel, Вы писали:

M>Это что получается у VB область активации локальной переменной ограничена методом но ни как ни блоком

M>"...поубывав бы гхадовь..."

Да... лучше тогда помахать VB .NET ручкой.... пока не пофиксят
... << RSDN@Home 1.0 beta 7 (MSSQL Edition) >>
Re: Я фигею от VB.NET
От: Lexey Россия  
Дата: 23.07.03 11:03
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?

Мда, уроды. Могу добавить другой прикол в коллекцию перлов от MS — на этот раз касательно VC++ 7.1.

Есть такой макрос:
#define DESTW buff
#define DebugMsgW(x) {\
        WCHAR buff[1024]; \
    wsprintfW x; \
    OutputDebugStringW(buff); \
}

Он зовется из метода кучу раз примерно так:
void SomeMethod()
{
    ...;
    DebugMsgW((DESTW, L"aaaa"));
    ...
}


Debug-версия, вызов метода идет внутри try/catch. В самом начале метода огребаем эксепшен STACK_OVERFLOW. Угадайте почему?
Re: Я фигею от VB.NET
От: Воронков Василий Россия  
Дата: 23.07.03 11:06
Оценка: :)
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Всем привет!


AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?

VB.NET рулит?
... << RSDN@Home 1.1 beta 1 >>
Re[2]: Я фигею от VB.NET
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.07.03 11:15
Оценка:
Здравствуйте, Gollum, Вы писали:

[]

G>0, 10, 10


Но почему?
Re[2]: Я фигею от VB.NET
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.07.03 11:15
Оценка:
Здравствуйте, migel, Вы писали:

[]

M>Неужто

M>0
M>10
M>10

Ага.
Re[3]: Я фигею от VB.NET
От: Gollum Россия  
Дата: 23.07.03 11:19
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

G>>0, 10, 10


AS>Но почему?


Потому что я не обратил внимание, что переменная объявляется в блоке Do Loop...
А вообще — странно все это...
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re[2]: Я фигею от VB.NET
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.07.03 11:28
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Здравствуйте, Alexey Shirshov, Вы писали:


[]

Нет идей. Почему?
Re: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.07.03 11:33
Оценка: +1
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Не перестаю удивляться крутым парням из MS

AS>
AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3
AS>

AS>Кто угадает какой будет вывод?

Аналог на шарпе просто не скомпилируется.
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[3]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 23.07.03 11:39
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Нет идей. Почему?


"Оптимизация", блин. Компилятор вытаскивает все объявления WCHAR buf[1024] наружу и складывает их в общую кучу (почему-то напрочь забывая про их реальный scope). При это размер резервируемой на стеке памяти в моем случае раздувается примерно до 180kb (против правильной цифры в районе 20-30). Попытка зарезервировать такой кусок на стеке внутри try/catch вызывает STACK OVERFLOW. Идиотизм, да и только.
Re[2]: Я фигею от VB.NET
От: alien74  
Дата: 23.07.03 11:59
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Alexey Shirshov, Вы писали:


AS>>Не перестаю удивляться крутым парням из MS

AS>>
AS>>        Dim ii As Integer = 0
AS>>        Do
AS>>            Dim j As Integer
AS>>            Console.WriteLine(j)
AS>>            j = 10
AS>>            ii += 1
AS>>        Loop While ii < 3
AS>>

AS>>Кто угадает какой будет вывод?

AVK>Аналог на шарпе просто не скомпилируется.


ага на шарпе будет:

Use of unassigned local variable 'j'

васик просто на это забивает

всетаки корректнее было бы написать Dim j As Integer = 0, и будет все нормально — три нуля
ведь дали же такую возможность, и для особо одаренных сказали что не очень корректно объявлять переменную без иницилизации, но можно
Re[3]: Я фигею от VB.NET
От: LCR Россия lj://_lcr_
Дата: 23.07.03 12:03
Оценка: -2
Здравствуйте, Alexey Shirshov, Вы писали:

G>>0, 10, 10


AS>Но почему?


AS>        Dim ii As Integer = 0
AS>        Do
AS>            Dim j As Integer
AS>            Console.WriteLine(j)
AS>            j = 10
AS>            ii += 1
AS>        Loop While ii < 3


На первой итерации цикла переменной j не существует, она создаётся и ей по умолчанию присваивается 0. После WriteLine j получает значение 10.
На второй итерации цикла переменная j уже существует, и поэтому инструкция "Dim j As Integer" ничего не делает.
То же самое на третьей итерации.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Я фигею от VB.NET
От: nob114  
Дата: 23.07.03 12:47
Оценка: -1
Kto ge peremnnuu vnutri tsikla objavlyaet ??? Objavite gde to eshe — a vistavit' mogno i v tsikle. Definitely buggy code.
Re[2]: Я фигею от VB.NET
От: alien74  
Дата: 23.07.03 12:51
Оценка:
Здравствуйте, nob114, Вы писали:

N>Kto ge peremnnuu vnutri tsikla objavlyaet ??? Objavite gde to eshe — a vistavit' mogno i v tsikle. Definitely buggy code.



в этом то и весь кайф что можно внутри цикла объявить в нете, а по окончании цикла убъется она

но в данном случае использование было некорректным
Re[2]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 23.07.03 12:52
Оценка:
Здравствуйте, nob114, Вы писали:

N>Kto ge peremnnuu vnutri tsikla objavlyaet ??? Objavite gde to eshe — a vistavit' mogno i v tsikle. Definitely buggy code.


В нормальных языках нормальные люди переменные объявляют по месту использования, в том числе и внутри циклов.
Re[3]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.07.03 13:07
Оценка:
Здравствуйте, Lexey, Вы писали:

L>В нормальных языках нормальные люди переменные объявляют по месту использования, в том числе и внутри циклов.


Я еще понимаю объявление переменных внутри объявления цикла, т.к. они будут сидеть в регистрах а не в стеке, но когда объявляют в середине кода, и начинаешь искать ее объявление начинаешь ....
Конечно дело вкуса, но мне нравится паскалевский подход.
и солнце б утром не вставало, когда бы не было меня
Re[4]: Я фигею от VB.NET
От: alien74  
Дата: 23.07.03 13:10
Оценка:
S> Конечно дело вкуса, но мне нравится паскалевский подход.


JEDEM DAS SEINE
Re[4]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 23.07.03 13:15
Оценка:
Здравствуйте, Serginio1, Вы писали:

L>>В нормальных языках нормальные люди переменные объявляют по месту использования, в том числе и внутри циклов.


S> Я еще понимаю объявление переменных внутри объявления цикла, т.к. они будут сидеть в регистрах а не в стеке, но когда объявляют в середине кода, и начинаешь искать ее объявление начинаешь ....


1) Когда нужно лезть в начало функции, чтобы увидеть объявление переменной — это ничуть не лучше, а в большинстве случаев гораздо хуже, т.к. в этом случае в месте объявления смысл переменной попросту непонятен.
2) Объявление по месту, в теории, позволяет компилятору генерировать более эффективный код.

S> Конечно дело вкуса, но мне нравится паскалевский подход.


У нас правило объявления переменной непосредственно перед началом ее использования внесено в корпоративный стандарт кодирования, и в данном случае я с ним полностью солидарен.
Re[5]: Я фигею от VB.NET
От: Awaken Украина  
Дата: 23.07.03 13:20
Оценка:
>хуже, т.к. в этом случае в месте объявления смысл переменной попросту непонятен.
L>2) Объявление по месту, в теории, позволяет компилятору генерировать более эффективный код.

зависит от реализации компилятора. если объявление переменной в цикле заставляет модифицировать фрейм стека
при каждом проходе это наоборот замедляет код. интересно как в этом случае поступает .NET — в скомпилированном коде
объявление будет вынесено за цикл?
Re[6]: Я фигею от VB.NET
От: migel  
Дата: 23.07.03 13:25
Оценка:
Здравствуйте, Awaken, Вы писали:

A>зависит от реализации компилятора. если объявление переменной в цикле заставляет модифицировать фрейм стека

A>при каждом проходе это наоборот замедляет код. интересно как в этом случае поступает .NET — в скомпилированном коде
A>объявление будет вынесено за цикл?
Будет, будет в IL Переменные обявляються в самом начале метода...
Просто компилятор басика не делает код активации в начале области видимости переменной
Re[5]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.07.03 13:28
Оценка:
Здравствуйте, Lexey, Вы писали:

L>2) Объявление по месту, в теории, позволяет компилятору генерировать более эффективный код.

Если переменные сидят в стеке, то какую либо оптимизацию получить сложно, тем более, что компилятору нужно следить за размещение в стеке, в отличии от объявления переменных внутри одной секции, т.к сразу определяется нужный размер стека под переменные.
Исключение составляют переменные циклов.
L>У нас правило объявления переменной непосредственно перед началом ее использования внесено в корпоративный стандарт кодирования, и в данном случае я с ним полностью солидарен.

Все зависит от длины куска кода, где применяется переменная, если небольшой вполне приемлемо, иначе....
и солнце б утром не вставало, когда бы не было меня
Re[6]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 23.07.03 13:31
Оценка:
Здравствуйте, Awaken, Вы писали:

>>хуже, т.к. в этом случае в месте объявления смысл переменной попросту непонятен.

L>>2) Объявление по месту, в теории, позволяет компилятору генерировать более эффективный код.

A>зависит от реализации компилятора. если объявление переменной в цикле заставляет модифицировать фрейм стека


Естественно. Только вынести объявление всегда можно, а вот внести гораздо сложнее. А локальное объявление, по идее, позволяет один раз зарезервировать память под множество однотипных временных переменных. Только вот VC с этим успешно не справляется.
Re[7]: Я фигею от VB.NET
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 23.07.03 14:06
Оценка:
Здравствуйте, migel, Вы писали:

[]

M>Просто компилятор басика не делает код активации в начале области видимости переменной


Это что значит?
Конструктор размерного типа-то вызывается!
Получается интересная картина: если объявлять переменную с помощью New, для нее конструктор вызывается каждый раз в цикле. Это касается и встроеных типов, типа integer.
Например,
Structure s
   Public i as Integer
   Public Sub New(j as Integer)
   End Sub
End Structure
...
Dim i as Integer
Do
   Dim j as Integer
   Dim t as s
   Dim tt as s(20)
   WriteLine(j)
   WriteLine(t.i)
   WriteLine(tt.i)
   j = 10
   t.i = 100
   tt.i = 200
Loop while i < 3

Вывод
0        <- j
0        <- t.i
20       <- tt.i

10       <- j
100      <- t.i
20       <- tt.i

10       <- j
100      <- t.i
20       <- tt.i
Re[8]: Я фигею от VB.NET
От: migel  
Дата: 23.07.03 14:51
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Здравствуйте, migel, Вы писали:


AS>[]


M>>Просто компилятор басика не делает код активации в начале области видимости переменной


AS>Это что значит?

AS>Конструктор размерного типа-то вызывается!
AS>Получается интересная картина: если объявлять переменную с помощью New, для нее конструктор вызывается каждый раз в цикле. Это касается и встроеных типов, типа integer.

Вот и получается что инициализация объекта не происходит при повторном входе в область видимости
Re[3]: Я фигею от VB.NET
От: nob114  
Дата: 23.07.03 14:57
Оценка: -2
Dumai nad slovami, otets.
Re: Я фигею от VB.NET
От: nob114  
Дата: 23.07.03 15:01
Оценка:
Ne proshe li initsializirovat' ee s predugadivaemim znacheniem ? Ne vigu ja, ubeite, nikakogo zdes' nikakogo kriminala...

AS> Dim ii As Integer = 0

AS> Do
AS> Dim j As Integer = 0 ' or whatever ya want
AS> Console.WriteLine(j)
AS> j = 10
AS> ii += 1
AS> Loop While ii < 3
Re[4]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.07.03 15:14
Оценка:
Здравствуйте, nob114, Вы писали:

N>Dumai nad slovami, otets.

Oy ctar uge stal synok, i dumat' uge len'.

А вот задумываться над тем как компилятор будет интерпретировать объявление переменной в цикле стоит.
и солнце б утром не вставало, когда бы не было меня
Re[5]: Я фигею от VB.NET
От: nob114  
Дата: 23.07.03 15:35
Оценка:
Ne vam adresovano bilo.
Re[6]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.07.03 15:48
Оценка:
Здравствуйте, nob114, Вы писали:

N>Ne vam adresovano bilo.

Izvinyayus'
и солнце б утром не вставало, когда бы не было меня
Re[4]: Я фигею от VB.NET
От: Tom Россия http://www.RSDN.ru
Дата: 23.07.03 16:06
Оценка:
N>Dumai nad slovami, otets.
Lexey был абсолютно прав. Таким образом обьявлять переменные абсолютно нормальная практика. Применятся в тех случаях когда переменная/обьект должна быть создана на каждой итерации цикла.

ЗЫ: У нас не принято обращаться в таком тоне. Будьте следующий раз аккуратнее.
... << RSDN@Home 1.1 beta 1 >>
Народная мудрось
всем все никому ничего(с).
Re: Я фигею от VB.NET
От: al Россия  
Дата: 23.07.03 17:11
Оценка: 3 (1)
Здравствуйте, Alexey Shirshov, Вы писали:

Фигеть нечего. Это называется совместимостью с предыдущими версиями языка.
в VB6 это код (вернее немного пдправленный код) делает то же самое:

     Dim ii As Integer
     ii = 0
        Do
            Dim j As Integer
            MsgBox j
            j = 10
            ii = ii + 1
        Loop While ii < 3


Так что фигеть следовало-бы в обратном случае.

PS
VB это не C#


Re[5]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.07.03 17:24
Оценка:
Здравствуйте, Tom, Вы писали:
Tom>Lexey был абсолютно прав. Таким образом обьявлять переменные абсолютно нормальная практика. Применятся в тех случаях когда переменная/обьект должна быть создана на каждой итерации цикла.

Не могли бы вы объяснить что будет происходить при объявление переменных Value типа.
Для объектов понятно выделяется память в куче, сборщик мусора пусть работает.
А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????
и солнце б утром не вставало, когда бы не было меня
Re[2]: Я фигею от VB.NET
От: Воронков Василий Россия  
Дата: 23.07.03 17:26
Оценка: +1
Здравствуйте, al, Вы писали:

Позволю себе не согласиться. Все же в VB.NET, в отличие от VB6, область видимости переменной ограничивается блоком, а не функцией. Так, в VB6 был бы вполне легален такой код:

If True Then
Dim i As Integer
i = 3
End If

MsgBox(i)


Более того, в диалог вывелось бы значение 3. В VB.NET же такой код просто не скомпилируется, так как там действительно используется с-подобная модель видимости переменных. Однако приведенный выше пример ее полностью нарушает. Таким образом, получается, что частично что-то переделали, а старые хвосты все же остались. Так что есть от чего фигеть на самом деле.
... << RSDN@Home 1.1 beta 1 >>
Re[5]: Я фигею от VB.NET
От: nob114  
Дата: 23.07.03 17:35
Оценка:
Vi post chitali ? U nas ne prinayato... Orli vi tut vse ja smotru....
Re[6]: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 04:17
Оценка:
Здравствуйте, nob114, Вы писали:

N>Vi post chitali ? U nas ne prinayato... Orli vi tut vse ja smotru....


Писать сообщения транслитом в этот форум запрещено.
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[6]: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 04:17
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????


Дергается стек
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re: Я фигею от VB.NET
От: Gollum Россия  
Дата: 24.07.03 05:28
Оценка:
Здравствуйте, 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.

LocalDeclarationStatement ::= LocalModifier LocalDeclarator StatementTerminator

LocalModifier ::= Static | Dim | Const

LocalDeclarator ::=
LocalIdentifiers [ As TypeName ]
Identifier [ ArrayNameModifier ]
[ As [ New ] TypeName [ ( [ ArgumentList ] ) ] ] [ = VariableInitializer ]

LocalIdentifiers ::=
Identifier [ ArrayNameModifier ] |
LocalIdentifiers , Identifier [ ArrayNameModifier ]

LocalVariableName ::= Identifier

... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re[7]: Я фигею от VB.NET
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 24.07.03 07:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????

AVK>Дергается стек

А как джит узнает, что надо дергать стек, если в мсиле все переменные объявляются в начале метода?
Re[6]: Я фигею от VB.NET
От: Tom Россия http://www.RSDN.ru
Дата: 24.07.03 07:53
Оценка:
Здравствуйте, 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 компилятор, а память выделяется только один раз.


ЗЫ: Это конечно всё теория. Теперь пойду проверять
... << RSDN@Home 1.1 beta 1 >>
Народная мудрось
всем все никому ничего(с).
Re[7]: Я фигею от VB.NET
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 24.07.03 08:28
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Ваш вопрос на самом деле очень интересный. На сях память в стеке для локальных переменных выделяется только один раз при входе в функцию.


Не всегда, я бы даже сказал, что обычно не так.

При таком коде vc6,7 (может и более ранние) сгенерирует код, при котором буфер будет выделен только при заходе в if. Это вроде даже где-то в стандарте зафиксировано.
if (condition)
{
  char buffer[10000];
}


зы
если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным
Re: Я фигею от VB.NET
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 24.07.03 08:32
Оценка:
Здравствуйте, Alexey Shirshov, Вы писали:

AS>Кто угадает какой будет вывод?


А что тебе не нравится?
Все логично даже просто с точки зрения здравого смысла.
Переменную j ты не инициализируешь сам, поэтому в ней может находится произвольный мусор, то что этот мусор является предыдущим значением — это уже частности.
Re[8]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 24.07.03 08:33
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>зы

DG>если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным

VC обычно использует ebp-based frame. Смещения локальных переменных в этом случае не меняются.
Re[4]: Я фигею от VB.NET
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 24.07.03 08:34
Оценка:
Здравствуйте, Lexey, Вы писали:

AS>>Нет идей. Почему?


> "Оптимизация", блин.


Попробуй добавить в define фигурные скобки — #define {bla-bla} или добавить if — #define if(true){bla-bla}
Re[2]: Я фигею от VB.NET
От: migel  
Дата: 24.07.03 08:35
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>Здравствуйте, Alexey Shirshov, Вы писали:


AS>>Кто угадает какой будет вывод?


DG>А что тебе не нравится?

DG>Все логично даже просто с точки зрения здравого смысла.
DG>Переменную j ты не инициализируешь сам, поэтому в ней может находится произвольный мусор, то что этот мусор является предыдущим значением — это уже частности.

Какой мусор?- по спецификации локальные переменные инициализируються значением по умолчанию.
Re[8]: Я фигею от VB.NET
От: Tom Россия http://www.RSDN.ru
Дата: 24.07.03 08:41
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>Здравствуйте, Tom, Вы писали:


Tom>>Ваш вопрос на самом деле очень интересный. На сях память в стеке для локальных переменных выделяется только один раз при входе в функцию.


DG>Не всегда, я бы даже сказал, что обычно не так.


DG>При таком коде vc6,7 (может и более ранние) сгенерирует код, при котором буфер будет выделен только при заходе в if. Это вроде даже где-то в стандарте зафиксировано.

DG>
DG>if (condition)
DG>{
DG>  char buffer[10000];
DG>}
DG>


DG>зы

DG>если смотреть asm многих реальных программ, то видно, что значение регистра sp внутри одной функции постоянно ползает. Соответственно и ползает величина смещения при обращении к локальным переменным

вот код, который генерирует 6-ка:
8:            if(true)
0040103B B9 01 00 00 00       mov         ecx,1
00401040 85 C9                test        ecx,ecx
00401042 74 07                je          main+3Bh (0040104b)
9:            {
10:               char buffer[10000];
11:               buffer[0] = 1;
00401044 C6 85 F0 D8 FF FF 01 mov         byte ptr [buffer],1


я нигде не вижу тут выделения памяти. может в 7-ке уже и по другому...
... << RSDN@Home 1.1 beta 1 >>
Народная мудрось
всем все никому ничего(с).
Re[5]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 24.07.03 08:45
Оценка:
Здравствуйте, DarkGray, Вы писали:

AS>>>Нет идей. Почему?


>> "Оптимизация", блин.


DG>Попробуй добавить в define фигурные скобки — #define {bla-bla} или добавить if — #define if(true){bla-bla}


Если внимательно посмотришь, скобки у меня там изначально были. Без них это бы просто не компилировалось. Не думаю, что if (true) тоже бы что-то дало. Компилятор не дурак — такие if-ы должен выбрасывать сразу. Я проблему решил, добавив макрос
#define USES_DEBUG() WCHAR __buf_[1024];

и вынеся таким образом объявление буфера в начало метода.

Но радости от этого совсем никакой. Смахивает на явный баг оптимизатора.
Re[9]: Я фигею от VB.NET
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 24.07.03 09:00
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>я нигде не вижу тут выделения памяти. может в 7-ке уже и по другому...


Приношу свои извинения. Я ошибся.
Принял за выделение локальных переменных передачу по значению больших данных:

_text:0044249F                 sub     esp, 8
_text:004424A2                 sub     esp, 8
_text:004424A5                 lea     ecx, [esp+0B8h+var_44]
_text:004424A9                 fstp    [esp+0B8h+var_B0]
_text:004424AD                 fsin
_text:004424AF                 fstp    [esp+0B8h+var_B8]
_text:004424B2                 call    sub_0_42C270
Re[3]: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 09:09
Оценка:
Здравствуйте, migel, Вы писали:

M>Какой мусор?- по спецификации локальные переменные инициализируються значением по умолчанию.


Это точно? Что то я нигде такого не встречал.
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[4]: Я фигею от VB.NET
От: Gollum Россия  
Дата: 24.07.03 09:47
Оценка:
Здравствуйте, 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.


Если приплюсовать сюда мой постинг Re: Я фигею от VB.NET
Автор: Gollum
Дата: 24.07.03
, то, в общем, все становится понятно.
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re[7]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 24.07.03 10:02
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????


AVK>Дергается стек


Тогда непонятно, почему на данном форуме защищается объявление переменных в цикле.
Или это корпоративный стиль программирования.

Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???

В предыдущем вопросе допустил неточность, так как под саму ссылку тоже нужно выделять место в стеке.

Извиняюсь за глупые вопросы, т.к. в Паскале таких ситуаций не возникает.
и солнце б утром не вставало, когда бы не было меня
Re[7]: Я фигею от VB.NET
От: migel  
Дата: 24.07.03 10:24
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????


AVK>Дергается стек

Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.
Re[8]: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 10:37
Оценка:
Здравствуйте, migel, Вы писали:

AVK>>Дергается стек

M>Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.

Вот именно что максимальный. А всякие Ldxxx и Stxxx никто не отменял
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[9]: Я фигею от VB.NET
От: migel  
Дата: 24.07.03 10:48
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, migel, Вы писали:


AVK>>>Дергается стек

M>>Нихрена ничего не дергается в прологе IL метода устанавливается макс. размер стэка еще при компиляции — поэтому в Runtime стек выделяется один раз при входе в метод.

AVK>Вот именно что максимальный. А всякие Ldxxx и Stxxx никто не отменял

ну дык память то не перераспределяется... да и на стэке объекты не создаються а просто грузятся через ldloc...
Как болеется?
Re[8]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 24.07.03 10:52
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>>> А что происходит с Value типом.Либо испльзуется старая переменная или каждый раз расширяется (сужается) стек ????


AVK>>Дергается стек


S> Тогда непонятно, почему на данном форуме защищается объявление переменных в цикле.

S>Или это корпоративный стиль программирования.

По моему это уже не раз было сказано:
1) Такое объявление зачастую гораздо нагляднее, чем объявление в начале метода.
2) Это единственный нормальный способ обеспечить вызов конструктора/деструктора локального для цикла объекта.
3) С точки зрения оптимизации этот вариант также предпочтителен. Вынос объявления из цикла делается тривиально оптимизатором, но возможны ситуации, когда такой вынос не просто бесполезен, а очен вреден.
Реальный пример такой ситуации, когда оптимизатор попросту ломает программу, криво вынося переменные наружу, я уже привел.

S> Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???


Смотря для чего. По скорости лучше первое, по памяти — второе.
Re[10]: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 10:57
Оценка:
Здравствуйте, migel, Вы писали:

AVK>>Вот именно что максимальный. А всякие Ldxxx и Stxxx никто не отменял

M>ну дык память то не перераспределяется...

А кто говорил про то что память перераспределяется?

M>Как болеется?


Сегодня уже ничего , хотя ничего хорошего
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[9]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 24.07.03 11:18
Оценка:
Здравствуйте, Lexey, Вы писали:



S>> Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???


L>Смотря для чего. По скорости лучше первое, по памяти — второе.


Под стек память уже выделна и можно говорить только о переполнении стека, что случается очень редко и такие ситуации можно предусмотреть заранее.

S>> 1) Такое объявление зачастую гораздо нагляднее, чем объявление в начале метода.

S>> 2) Это единственный нормальный способ обеспечить вызов конструктора/деструктора локального для цикла объекта.


Так наверное лучше определить в конструкции цикла, чем в теле цикла, зачем понапрасну дергать стек???

А причем тут конструктор/деструктор и объявление переменной ????
Конструктор вызывай сколько угодно раз, один раз объявив переменную,
Для Деструкторов есть using

И такой код совсем не нагляден. О чем говорит выше приведенный код.

А наглядность это дело вкуса. Главное эффективность и понятность кода.
В принципе на свой вопрос ответ я получил.
и солнце б утром не вставало, когда бы не было меня
Re[3]: Я фигею от VB.NET
От: al Россия  
Дата: 24.07.03 11:27
Оценка:
Здравствуйте, Воронков Василий, Вы писали:


ВВ>Более того, в диалог вывелось бы значение 3. В VB.NET же такой код просто не скомпилируется, так как там действительно используется с-подобная модель видимости переменных. Однако приведенный выше пример ее полностью нарушает. Таким образом, получается, что частично что-то переделали, а старые хвосты все же остались. Так что есть от чего фигеть на самом деле.


Так все дело в том, что в Вашем случае компилятор сообщит об ошибке, и при необходимости программист вынесет объявление переменной из блока if. А в начальном примере компилятор не увидит ничего криминального, но если он просто так изменит поведение программы с VB6 на C#-подобное, то это будет не правильно. Между прочем, если использовать объявление в стиле VB.Net


 Dim ii As Integer = 0
        Do
            Dim j As Integer  = 0 
            Console.WriteLine(j)
            j = 10
            ii += 1
        Loop While ii < 3


то аоведение прогрммы меняется, и мы получаем три нуля, как в C#


Re[10]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 24.07.03 11:33
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Lexey, Вы писали:




S>>> Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???


L>>Смотря для чего. По скорости лучше первое, по памяти — второе.


S>Под стек память уже выделна и можно говорить только о переполнении стека, что случается очень редко и


Зарезервирована != используется. Использование еще может потребовать дополнительного commit'а страниц, а это далеко не бесплатная операция.

такие ситуации можно предусмотреть заранее.

Такие ситуации далеко не всегда можно предусмотреть заранее. Пример я приводил. Код совершенно корректен, а результат — нет.

S>>> 1) Такое объявление зачастую гораздо нагляднее, чем объявление в начале метода.

S>>> 2) Это единственный нормальный способ обеспечить вызов конструктора/деструктора локального для цикла объекта.


S> Так наверное лучше определить в конструкции цикла, чем в теле цикла, зачем понапрасну дергать стек???


В смысле в for? Не канает, т.к. это почти равносильно объявлению вне цикла (кроме области видимости).

S> А причем тут конструктор/деструктор и объявление переменной ????

S> Конструктор вызывай сколько угодно раз, один раз объявив переменную,
S>Для Деструкторов есть using

Я вообще-то не привязывался к дотнету. В C++ конструктор вызывается ровно один раз, равно как и деструктор.

S> И такой код совсем не нагляден. О чем говорит выше приведенный код.


Не говорит. Этот код говорит, что MS подложила разработчикам большую свинью, пообещав автоматическую инициализацию value-типов, но реализовав ее в случае VB.NET через задницу. Как уже говорилось, в C# потребуется указать явный инициализатор, после чего все будет работать как надо.

S> А наглядность это дело вкуса. Главное эффективность и понятность кода.


Наглядность это часть понятности. Про эффективность я тоже уже говорил — теоретически, она у локальных объявлений выше.
Re: Я фигею от VB.NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.03 11:37
Оценка:
На всякий случай приведу IL приведенного кода

.method public instance void  Y() cil managed
{
  // Code size       20 (0x14)
  .maxstack  2
  .locals init (int32 V_0,
           int32 V_1)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  ldloc.1
  IL_0003:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0008:  ldc.i4.s   10
  IL_000a:  stloc.1
  IL_000b:  ldloc.0
  IL_000c:  ldc.i4.1
  IL_000d:  add.ovf
  IL_000e:  stloc.0
  IL_000f:  ldloc.0
  IL_0010:  ldc.i4.3
  IL_0011:  blt.s      IL_0002
  IL_0013:  ret
} // end of method X::Y
... << RSDN@Home 1.1 beta 1 (np: тихо) >>
AVK Blog
Re[11]: Я фигею от VB.NET
От: Gollum Россия  
Дата: 24.07.03 11:39
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Не говорит. Этот код говорит, что MS подложила разработчикам большую свинью, пообещав автоматическую инициализацию value-типов, но реализовав ее в случае VB.NET через задницу. Как уже говорилось, в C# потребуется указать явный инициализатор, после чего все будет работать как надо.


Ну, в Language Referenсe об этом все сказано, так что свиньи никакой нет. "Если ничего не получается — прочитайте, наконец, инструкцию" (с).

Так что нужно инициализировать явно.
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re[12]: Я фигею от VB.NET
От: Lexey Россия  
Дата: 24.07.03 11:47
Оценка:
Здравствуйте, Gollum, Вы писали:

L>>Не говорит. Этот код говорит, что MS подложила разработчикам большую свинью, пообещав автоматическую инициализацию value-типов, но реализовав ее в случае VB.NET через задницу. Как уже говорилось, в C# потребуется указать явный инициализатор, после чего все будет работать как надо.


G>Ну, в Language Referenсe об этом все сказано, так что свиньи никакой нет. "Если ничего не получается —


Ну да, только тебе не кажется, что это замечание в language reference логически противоречит утверждению об автоматической инициализации переменных?

>прочитайте, наконец, инструкцию" (с).


Всех инструкций не перечитаешь. Некоторые вещи проще делаются на нормальной логике, а тут она слегка отсутствует.
Re[13]: Я фигею от VB.NET
От: Gollum Россия  
Дата: 24.07.03 11:54
Оценка:
Здравствуйте, Lexey, Вы писали:

>>прочитайте, наконец, инструкцию" (с).


L>Всех инструкций не перечитаешь. Некоторые вещи проще делаются на нормальной логике, а тут она слегка отсутствует.


Согласен. Но формально MS упрекнуть не в чем.
... << RSDN@Home 1.1 beta 1 >>
Eugene Agafonov on the .NET

Re[11]: Я фигею от VB.NET
От: migel  
Дата: 24.07.03 11:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:

M>>ну дык память то не перераспределяется...


AVK>А кто говорил про то что память перераспределяется?

Гм наверное я так понял фразу "...стек дергается...", а в IL В месте объявления переменной никаких загрузок в стек не происходит — только по требованию....

AVK>Сегодня уже ничего , хотя ничего хорошего


Выздорваливай.
Re[11]: Я фигею от VB.NET
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 24.07.03 12:04
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, Lexey, Вы писали:




S>>>> Что лучше за один раз передвинуть вершину стека, или это делать для каждой переменной???


L>>>Смотря для чего. По скорости лучше первое, по памяти — второе.


S>>Под стек память уже выделна и можно говорить только о переполнении стека, что случается очень редко и


L>Зарезервирована != используется. Использование еще может потребовать дополнительного commit'а страниц, а это далеко не бесплатная операция.


Дополнительный commit потребуется при выделении следующей страницы, а она возникает не часто, тем более учитывая, что декомит возникает редко, чай памяти достаточно. А эффективность выше.

L>такие ситуации можно предусмотреть заранее.



S>>>> 1) Такое объявление зачастую гораздо нагляднее, чем объявление в начале метода.

S>>>> 2) Это единственный нормальный способ обеспечить вызов конструктора/деструктора локального для цикла объекта.


S>> Так наверное лучше определить в конструкции цикла, чем в теле цикла, зачем понапрасну дергать стек???


L>В смысле в for? Не канает, т.к. это почти равносильно объявлению вне цикла (кроме области видимости).


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

S>> А причем тут конструктор/деструктор и объявление переменной ????

S>> Конструктор вызывай сколько угодно раз, один раз объявив переменную,
S>>Для Деструкторов есть using

L>Я вообще-то не привязывался к дотнету. В C++ конструктор вызывается ровно один раз, равно как и деструктор.


В Delphi для переменной вызывай конструктор, деструктор сколько дуще угодно.

L>Наглядность это часть понятности.

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

Много говорилось об оптимизации компилятора, то желательно знать и предугадывать действия компилятора и кодировать оптимальный код. Хотя Delphi и не VС++ но программируя на Паскале можно добиваться очень эффективной компиляции перед которой Ассемблеристы пасуют, но для этого нужно знать как в той или иной ситуации компилятор будет интерпретировать высокоуровневый код.
и солнце б утром не вставало, когда бы не было меня
Re[2]: Я фигею от VB.NET
От: migel  
Дата: 24.07.03 12:37
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>На всякий случай приведу IL приведенного кода


AVK>
AVK>.method public instance void  Y() cil managed
AVK>{
AVK>  // Code size       20 (0x14)
AVK>  .maxstack  2
AVK>  .locals init (int32 V_0,
AVK>           int32 V_1)

      // Вот это то и есть установка дефолтного значения
      IL_0000:  ldc.i4.0
      IL_0001:  stloc.0

....
      // по хорошему же конечно надо было бы blt.s IL_0000
      IL_0011:  blt.s      IL_0002
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.