121
Функции с переменным количеством элементов
Функции с переменным количеством аргументов также являются
потенциальным источником проблем. В отличие от обычных функций,
имеющих прототип, стандартом не регламентируется проверка функций с
переменным числом аргументов. Если передаётся неправильный тип данных, то
возникает непредсказуемый, если не фатальный результат. Например, семейство
функций printf стандартной библиотеки языка
Си, используемое для генерации
форматированного текста для вывода, хорошо известно своим потенциально
опасным интерфейсом с переменным числом аргументов, которые описываются
строкой формата. Проверка типов в функциях с переменным числом аргументов
является задачей каждой конкретной реализации такой функции, однако многие
современные компиляторы проверяют типы в каждом вызове printf, генерируя
предупреждения в случаях, когда
список аргументов не соответствует строке
формата. Следует заметить, что невозможно статически проконтролировать
даже все вызовы функции printf, поскольку строка формата может создаваться в
программе динамически, поэтому, как правило, никаких проверок других
функций с переменным числом аргументов компилятором не производится. Для
помощи программистам на Си в решении этих и многих других проблем
было
создано большое число отдельных от компиляторов инструментов. Такими
инструментами являются программы дополнительной проверки исходного кода
и поиска распространённых ошибок, а также библиотеки, предоставляющие
дополнительные функции, не входящие в стандарт языка, такие как проверка
границ массивов или ограниченная форма сборки мусора.
Проблемы стандартной библиотеки языка С
Ещё одной распространённой проблемой является
то, что память не может
быть использована снова, пока она не будет освобождена программистом с
помощью функции free(). В результате программист может случайно забыть
освободить эту память и продолжить её выделять, занимая всё большее и
большее пространство. Это обозначается термином утечка памяти. Наоборот,
возможно освободить память слишком рано, но продолжать её
использовать.
Из-за того, что система выделения может использовать освобождённую память
по-другому, это ведёт к непредсказуемым последствиям. Эти проблемы
решаются в языках со сборкой мусора. С другой стороны, если память
выделяется в функции и должна освобождаться после выхода из функции,
данная проблема решается с помощью автоматического вызова деструкторов в
языке
C++, или с помощью локальных массивов, используя расширения С99.
Оптимизация программ для микроконтроллеров
Программирование микроконтроллеров существенно отличается от
программирования систем общего назначения, так как информационно-
управляющие системы, встроенные системы и микроконтроллеры имеют