Знатокам стандартов C/C++ (об инициализации локальных переменных)

Тема в разделе "WASM.ZEN", создана пользователем clone, 28 окт 2006.

  1. clone

    clone New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    84
    Код (Text):
    1. void f()
    2. {
    3.     int a[10] = {};
    4.    
    5.     ...
    6.  
    7. }
    Вопрос: что говорят стандарты? Должен ли массив быть инициализирован нулями или этот случай "compiler dependent" и может иметь место простое резервирование памяти на стеке?
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    а что мешает сделать {0} и не заморачиваться мыслью должен или не должен?
     
  3. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    В книгах по С++ обычно рекомендуют инициализировать члены класса, а вот про локальные переменные я что-то не слышал. И потом, все зависит от контекста процедуры, как ты собираешься с этим массивом обращаться. Если ты уверен, что все его элементы будут корректно установлены и не требуется инициализации дефолтными значениями, тогда забей на него. Если же есть сомнения, тогда инициализируй.
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    В массиве будет хлам (остатки предыдущих значений, хранившихся в стеке). Никто специально для тебя не будет чистить стек по выходе из процедур. Как будто винде больше время тратить не на что, кроме как на зачистку сегмента стека после выполнения процедур.
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    clone
    Стандарт вообще такой изврат не поддерживает, afaik. Инициализация - это операция, которую осуществляет компилятор на этапе компиляции, а не в рантайме. Вот пример инициализации, который будет правильно воспринят любым стандартным компилятором C/C++:
    Код (Text):
    1. char a[10] = {1,2,3};
    Здесь a - это глабальный массив. Первые 3 байта будут проинициализированы значениями 1, 2 и 3. Остальные 7 - значением по умолчанию, которым обычно является ноль. Чтобы инициализация значением по умолчанию остальных байтов массива (или полей структуры) имело место быть, должен быть явно указан хотя бы один элемент (естественно, первый) данного массива. Поэтому {0} не равно {}.

    Теперь перейдём к локальным переменным:
    Код (Text):
    1. void f1(void){
    2. char a[10] = {1,2,3};
    3. /* ... */
    Есть компиляторы C, которые вообще такое не переваривают и имеют на это полное право, т.к. это уже не инициализация (это будет присваивание в рантайме). Слово static исправляет этот конфликт со стандартом:
    Код (Text):
    1. void f1(void){
    2. static char a[10] = {1,2,3};
    3. /* ... */
    Но такое решение не всегда приемлемо.

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

    clone New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    84
    Asterix
    Чем в данном случае `{}' отличается от {0}?

    crypto
    Классы тут и рядом не валялись.

    cresta
    Мне лично такой вариант нравится, но см. топик и внимательно читай первый пост.

    Quantum
    AFAYK меня мало интересует (см. топик и вопрос)

    следующая фраза адресована всем
    Речь -- повторяю -- о стандартах.
     
  7. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    clone
    Прочитай внимательнее мой предыдущий ответ.

    Хорошо, читай стандарт самостоятельно и делай выводы сам, если речь вообще о действующем стандарте ANSI C99 или C++ 98, а не о каком-то метастандарте, обьединяющем особенности популярных компиляторов.

    Конкретно в ISO/IEC 9899:1999 (это последний стандарт ANSI C99) можно найти следующее про инициализацию локальных массивов:
    aggregate значит массив или struct, automatic - это локальная переменная.
     
  8. clone

    clone New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    84
    Quantum
    из
    не следует, что
     
  9. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    clone
    Про синтаксис brace-enclosed list - это в другом разделе. Чтобы понять, нужно прочитать книжку полностью. Бесплатный драфт называется n1124.pdf.
     
  10. fr0b-p

    fr0b-p New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2006
    Сообщения:
    118
    н-да понаписали...

    итак:

    есть знак = и это объявление с явной инициализацией

    а дальше уже зависит от языка...

    это не валидный ISO/IEC 9899:1999 С см синтаксис §6.7.8
    initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
    и не скомпилится

    это валидный ISO/IEC 14882:2003 С++ см синтаксис 8.5
    initializer:
    = initializer-clause
    ( expression-list )
    initializer-clause:
    assignment-expression
    { initializer-list ,opt }
    { } // вот оно
    и массив будет инициализирован дефолтным значением для типа int то есть 0
    инициализация будет в рантайме!


    а что там пишут про инициализацию компилятором (на самом деле линкером) так это относится с объектам статического класса памяти...
     
  11. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    fr0b-p
    Инициализация обычных локальных агрегатов vs. статических локальных или вообще глобальных, стандартом рассматривается в разных секциях. Я привёл цитату именно по локальным не статическим агрегатам.
     
  12. clone

    clone New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    84
    Я на свой вопрос получил более, чем исчерпывающий ответ, и -- если нет желающих пофлеймить на сопряжённые темы -- топик можно закрывать.