Date Редакция Категория comp Теги C

Листая слайды Deep C (and C++), натолкнулся на интересные примеры того, насколько язык С нацелен на скорость выполнения программы. Вроде бы все просто, но мне самому в голову эти соображения как-то не пришли... Делюсь.

Почему значение статических переменных по умолчанию устанавливается равным нулю, тогда как автоматические переменные инициализируются мусором?

Инициализация статических переменных выполняется всего один раз, в самом начале выполнения программы. Напротив, автоматические переменные пришлось бы устанавливать равными 0 при каждом вызове функции. Всякий раз на это тратилось бы дополнительное время, и, следовательно, замедлялось бы выполнение программы. Вместо этого С просто не делает ничего, кроме того, что явным образом указывает ему программист: то есть не инициализирует "сам по себе" автоматические переменные и не заботится об очистке занятых ими ячеек памяти.

Почему структура выравнивается по умолчанию?

Программа

#include <stdio.h>

struct X { int a; char b; int c; };

int main()
{
    printf("%zu,", sizeof(int));
    printf("%zu,", sizeof(char));
    printf("%zu\n", sizeof(struct X));
}

выполненная на 32-разрядной машине, скорее всего выведет

4,1,12

Понятно, что полученный размер структуры вызван выравниванием ее полей. Ясно, что выравнивание можно отменить, заставив компилятор "упаковать" структуру плотнее: в gcc это делается опцией -fpack-struct. Но вот почему именно выравнивание сделано поведением по умолчанию?

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

P. S. %zu -- спецификатор формата для печати переменных типа size_t (C99).



Комментарии

comments powered by Disqus