Конференция "Начинающим" » Дефолтная инициализация глобальных в Delphi
 
  • KSergey © (15.07.18 11:39) [0]
    В документации не нашёл (верю, что есть), но google подсказывает много мест, где скопирован один и то же текст про инициализацию переменных.
    В частности, про глобальные переменные там есть пункт:

    > Global variables are always initialized to 0 etc as well;

    Но вот вопрос: что будет с глобальными переменными типа record? все поля глобальной структуры проинициализируются нулями? или приведённая цитата относится только к переменным "не составных" типов (т.е. только к int, double и т.п.)?
    Или можно быть уверенным, что, например, вот в такой глобальной переменной первое поле осле старта приложения будет nil, а второе false?

    var
    GlobVar = record
       obj: TObject;
       isInited: Boolean;
    end;
  • Styx © (15.07.18 12:12) [1]
    По идее неинициализированные переменные помещаются в сегмент BSS, который инициализируется нулями при загрузке программы загрузчиком ОС. Можно сделать Detailed-Segments Map File, чтобы убедиться, что Ваша запись туда попала.
  • dmk © (15.07.18 13:12) [2]
    А проверить сложно? Т.е. прочитать переменную.
  • Плохиш © (15.07.18 13:26) [3]
    В чём проблема проинициализировать переменные самому?
  • KilkennyCat © (15.07.18 13:32) [4]
    Не знаю, как сейчас, а в D7-WinXP мне пришлось инициализировать самому структуру с массивом - в массиве был мусор.
  • KSergey © (15.07.18 15:58) [5]
    > KilkennyCat ©   (15.07.18 13:32) [4]
    > Не знаю, как сейчас, а в D7-WinXP мне пришлось инициализировать
    > самому структуру с массивом - в массиве был мусор.

    Про массив - не верю, признаться.
    Очевидно, что строки и (динамические) массивы и т.п. "волшебные штуки" Delphi гарантированно инициализирует. Иначе бы ничего неработало. (Да и про это явно написано в там же, "по-умному" называются
    А, или вероятно речь не про динамический массив, а про статический как поле структуры? тогда да, тогда это показательно (мы про глоб. переменную, верно?)
  • KSergey © (15.07.18 16:00) [6]
    > dmk ©   (15.07.18 13:12) [2]
    > А проверить сложно? Т.е. прочитать переменную.

    undefined behavior? нет, не слышал
  • KSergey © (15.07.18 16:02) [7]
    > Styx ©   (15.07.18 12:12) [1]

    Мысль сама по себе клёвая, но мне боязно подкладывать такую мину.
    (сейчас-то я проверю, а что будет после смены компилятора, например? никто ж не вспомнит про такой хитровыпученный нюанс и не проверит)
  • sniknik © (15.07.18 17:11) [8]
    > после смены компилятора
    а компилятор тут не причем, это система выделяет память под данные и зануляет выделенное. переменные в программе/для компилятора это всего лишь адреса в этой выделенной памяти.
    те. виндой если так понятнее (Styx - загрузчиком ОС).
    добавлю, на линуксе под вайном ловил глюки с неопределенным начальным значением глобальных переменных (давно, уже читал пофиксено, но все равно все нужное с тех пор инициализирую сам, не рассчитывая на систему). в винде такого не было никогда.
  • Игорь Шевченко © (15.07.18 23:15) [9]
    sniknik ©   (15.07.18 17:11) [8]

    Это не единственный глюк в вайне.

    KSergey ©   (15.07.18 11:39)  


    > Но вот вопрос: что будет с глобальными переменными типа
    > record? все поля глобальной структуры проинициализируются
    > нулями?


    Все поля проинициализируюстся нулями.
  • kilkennycat © (16.07.18 00:55) [10]

    > KSergey ©   (15.07.18 15:58) [5]

    я не помню, динамический или статический был. вроде, именно динамический. И на самом деле, мусор совершенно не противоречит работе, с чего вдруг ничего бы не работало? Выделилась память, в памяти что-то было - вот и мусор. Заполнение памяти нулями иль чем-то иным (например, при прогоне через усб лучше FF) - рядовое явление после объявления массива.
    На эту тему как-то давно на встрече в Москве спорили, тож некоторые считали, что мусора не будет.
    Но я помню, тогда еще эксперимент проводил - объявлял максимально большой массив, смотрел его дамп и узнавал обрывки данных.
  • KSergey © (16.07.18 08:26) [11]
    > kilkennycat ©   (16.07.18 00:55) [10]
    > я не помню, динамический или статический был. вроде, именно
    > динамический. И на самом деле, мусор совершенно не противоречит
    > работе, с чего вдруг ничего бы не работало?

    Штука в том, что состояние динамического массива должно быть гарантировано корректным в любое время.
    А потому, если
     s: String;
    или
     a: array of integer;
    компилятор не проинициализирует нулями гарантированно - то первая же любая работа с ними приведёт к обращению в недоступную память.
    Ну, понятно же, что SetLength(aб 5) сначала должно освободить ранее выделенную под массив память, тут-то и произойдёт бабах
  • KSergey © (16.07.18 08:26) [12]
    SetLength(a, 5)
    я хотел сказать
  • KSergey © (16.07.18 08:30) [13]
    > компилятор не проинициализирует нулями гарантированно

    я имею ввиду саму (внутреннюю) структуру массива, не значения элементов после того, как память выделили; значения элементов как раз остаются с мусором и это понятно и тут проблем нет.
  • KSergey © (16.07.18 08:30) [14]
    Всем спасибо за обсуждение, я понял.
  • KilkennyCat © (16.07.18 09:57) [15]

    > KSergey ©   (16.07.18 08:30) [13]

    ну да, всё верно.
  • han_malign © (19.07.18 18:08) [16]

    > На эту тему как-то давно на встрече в Москве спорили, тож некоторые считали, что мусора не будет.

    - заполнение нуля при увеличении размера через SetLength() - документировано...

    System.DynArraySetLength:
    ...
     // Set the new memory to all zero bits
     FillChar((PChar(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

    ...

    про BSS  уже говорили...
    Мусор будет при размещении на стеке, и может зависеть от реализации менеджера памяти для чистых SysGetMem/SysReallocMem()
  • KSergey © (21.07.18 13:32) [17]
    > han_malign ©   (19.07.18 18:08) [16]

    Прикольно, в самом деле есть такой кусок.
    Похоже парни решили не заморачиваться интеллектом в компиляторе, и, не разбираясь в фактически хранящихся данных в массиве, прописывают 0 в любом случае на всю новую память.
    (хотя это гарантированно надо лишь для случая, когда в массиве элементы имеют тип с волшебно управляемым менеджментом, например строки).
    Хотя чуть выше в этом же месте освобождают память (при уменьшении размера массива) вполне себе с интеллектом.
 
Конференция "Начинающим" » Дефолтная инициализация глобальных в Delphi
Есть новые Нет новых   [134427   +34][b:0][p:0.001]