Язык программирования Си для персонального компьютера
Шрифт:
Текущий номер строки и имя исходного файла доступны в программе через псевдопеременные с именами __LINE__ и __FILE__. Эти псевдопеременные могут быть использованы для выдачи во время выполнения сообщений о точном местоположении ошибки.
Значением псевдопеременной __FILE__ является строка, представляющая имя файла, заключенное в двойные кавычки. Поэтому для печати имени исходного файла не требуется заключать сам идентификатор __FILE__ в двойные кавычки.
Примеры.
/* пример 1 */
#line 151 "copy.с"
/*
#define ASSERT(cond) if (!cond)\
{printf ("ошибка в строке %d файла %s\n", \
__LINE__, __FILE__);} else;
В первом примере устанавливается имя исходного файла сору.с и текущий номер строки 151.
Во втором примере в макроопределении ASSERT используются псевдопеременные __LINE__ и __FILE__ для печати сообщения об ошибке, содержащего координаты исходного файла, если некоторое условие, заданное макроаргументом cond, ложно.
Директива обработки ошибок
В СП ТС реализована директива #error. Ее формат:
#error <текст>
Обычно эту директиву записывают среди директив условной компиляции для обнаружения некоторой недопустимой ситуации. По директиве #error препроцессор прерывает компиляцию и выдает следующее сообщение:
Fatal: <имя-файла> <номер-строки> Error directive: <текст>
Fatal — признак фатальной ошибки; <имя-файла> — имя исходного файла; <номер-строки> — текущий номер строки; Error directive — сообщение об ошибке в директиве; <текст> — собственно текст диагностического сообщения.
Например, если именованная константа MYVAL может иметь значение либо 0, либо 1, можно поместить в исходный файл операторы условной компиляции для проверки на некорректное значение MYVAL:
#if (MYVAL != 0 && MYVAL != 1)
#error MYVAL должно иметь значение либо 0, либо 1
#endif
Препроцессор просматривает текст сообщения в директиве #error, и исключает из него комментарии (если они имеются), но именованные константы и макроопределения в тексте не выявляет и макроподстановку не производит.
Пустая директива
Для повышения читабельности программ СП ТС распознает пустую директиву, состоящую из строки, содержащей просто знак #. Эта директива всегда игнорируется.
Указания компилятору языка Си
Синтаксис:
#pragma <последовательность-символов>
Указания компилятору, или прагмы, предназначены для исполнения компилятором
Набор прагм для каждого компилятора языка Си различен. Для получения подробной информации о прагмах смотрите системную документацию по используемому вами компилятору.
Псевдопеременные
Псевдопеременные представляют собой зарезервированные именованные константы, которые можно использовать в любом исходном файле. Каждый из них начинается и оканчивается двумя символами подчеркивания (__).
__LINE__
Номер текущей обрабатываемой строки исходного файла—десятичная константа. Первая строка исходного файла имеет номер 1.
__FILE__
Имя компилируемого исходного файла — символьная строка. Значение данной псевдопеременной изменяется каждый раз, когда компилятор обрабатывает директиву #include или директиву #line, а также по завершении включаемого файла.
Следующие две псевдопеременные поддерживаются только СП ТС.
__DATE__
Дата начала компиляции текущего исходного файла — символьная строка. Каждое вхождение __DATE__ в заданный файл дает одно и то же значение, независимо от того, как долго уже продолжается обработка. Дата имеет формат mmm dd УУУУ, где mmm — месяц (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec), dd — число текущего месяца (1…31; в 1-й позиции dd ставится пробел, если число меньше 10), уууу — год (например, 1990).
__TIME__
Время начала компиляции текущего исходного файла — символьная строка. Каждое вхождение __TIME__ в заданный файл дает одно и то же значение, независимо от того, как долго уже продолжается обработка. Время имеет формат hh:mm:ss, где hh — час (00…23), mm — минуты (00…59), ss — секунды (00…59).
МОДЕЛИ ПАМЯТИ
Реализация моделей памяти в СП MSC и в СП ТС имеет ряд отличий. В разделах 8.1 и 8.2 описаны модели памяти СП MSC, а в разделе 8.3 приведены отличия моделей памяти СП ТС.
Виды моделей
Применение моделей памяти позволяет контролировать распределение памяти в программе и делать его более эффективным или адекватным решаемой задаче. По умолчанию в процессе компиляции и редактирования связей генерируется код для работы в малой (small) модели. Для большинства программ этой модели достаточно. Существуют, однако, два условия, когда малая модель не годится; если программа удовлетворяет хотя бы одному из них, следует использовать другую модель памяти: