GCC - The Complete Reference (537669), страница 19
Текст из файла (страница 19)
Для подавления подобных проблем в СзСС имеется опция -аозс-1пяо, которая может быть использована для автоматической генерации прототипов функций. Далее следует пример команды, которая создает заголовочный файл в1шмк1с. П, содержащий прототипы для всех определяемых в исходном файле в1лвех1с. с функций: $9сс в1юихх. с -апх-1пко в1гпикх.в 8 ясс ь.с -впх-1пко ргососурев.в Функции в программах на языке С могут быть преобразованы к форме стандарта "А!ЧЫ С" использованием утилиты ркоео1яе. Это более подробно описано в главе 14. Расширения бй0 языка С Компилятор СгСС не только может быть установлен на работу в соответствии с правилами одного нз стандартов языка С использованием таких опций как -апай или -вест, но также и может использовать некоторые собственные расширения.
Многие из расширений СХ(1 языка С прошлых версий компилятора ССС вошли в новые стандарты языка С. В следующих разделах рассмотрены лишь те расширения ССС, А следующая команда может быть использована для создания прототипов (они будут помещены в ркососурев. Ь) для функций всех исходных файлов на языке С в текущем каталоге: которые не являются частью известных стандартов. За исключением нескольких особых случаев, рассматриваемые расширения языка применяются только в ОСС. При назначении опции -ребапсдо, равно как и некоторых других, использование расширений ОЬ][) вызовет выдачу компилятором предупредительных сообщений. Однако, вы можете подавлять выдачу таких предупреждений, если используете ключевое слово ехсепв1оп перед расширенными выражениями.
Благодаря особой внутренней структуре ОСС, многие из описываемых здесь расширений применимы в С++ и О[усе(>те-С, так же как и в С. Компиляторы С++ и О(]]есггте-С используют части компилятора С, а это значит, что дополнения языка С и лрепроцессора СРР в ряде случаев распространяются также и на другие языки.
Однако, некоторые из расширений языка С конфликтуют с основными определениями других языков, поэтому онн отключены или несколько изменены в языках С++ и Офес((те-С. Выравнивание (А!~уипеп1) Оператор а11дпЕ возрашает границы выравнивания типа или отдельного элемента данных. Следующая программа показывает выравнивание каждого из типов данных: /* а11дп.с / ()Епо1иое <вес][о. Ьь суредеЕ всгпее [ Доивъв дта1пвг 1пг 1тга1пег ) вЬома1; Епс аа1п(1пе агдс,еЬаг *агдтг[)) ( Действующие правила выравнивния типов изменяются в зависимости от возможностей применяемой аппаратной базы.
Они могут либо определяться абсолютными требованиями применяемого оборудования либо устанавливаться в настройках предлагаемых границ выравнивания для более эффективного доступа к данным, Безымянные (анонимные) объединения (Апопипоы 0п~опз) Внутри структуры [з(п>с() возможно объявление объединения (ппйоп) без имени, что делает возможным адресоваться к членам этого объединения напрямую, так рг1пеЕ рг1пЕЕ рг1пеЕ ргзпсЕ рг1пСЕ рг1пСЕ рг1пЕЕ ргзпЕЕ геепгп Глава 4. Компиляция программ на языке С 35 (" а11дпоЕ (енаг)=тв11п", а11дпоЕ (спаг))г (" а11дпоЕ (вЬогс)=тгк)1п", а1).дпоЕ (вЬогс>]; (" а11дпоЕ (1пе)=тм11п", а11дпоЕ (1пс])Г (" а11дпоЕ (1опд]=км)1п", а11дпоЕ (1опд))] (" а11дпоЕ (1опд 1опд)=Ъй1п", а11дпоЕ (1опд 1опд)) (" а11дпоЕ (Е1оаС)=км)1п", а11дпоЕ (Е1оае))г (" а11дпоЕ (ооиЬ1в> ЪЛЪп", а11дпоЕ (((оиЬ1е))> (" а1).дпоЕ (вцома1)=ткг)1п", а11дпоЕ (вЬома1))г <о>; 86 Часть )). Использование Сборного Компилятора как если бы они были членами структуры.
В следующем примере один блок из че- тырех байт обеспечивается двумя именами и двумя типами данных: всгисс ( сЬаг сопег ип1оп ( сЬаг сЬ16[4)г [пс пиегйг )г сЬаг епаеег ) еогхг Члены этой структуры могут быть адресованы как гаогх. собе, л(огх.сЬ11(), гаогх. пиша() и гаогх. пагле. Массивы переменной длины (Аггауя оФ ЧапаЫе ~елями) Массив может быть объявлен так, что его размер определяется во время выполнения программы. Это достигается использованием выражения в качестве вложенного в объявление сценария.
Например, следующая функция принимает две строки и объединяет нх в одну, вставляя между ними пробел: уо1д саеЬ[пе(сдаг *вег1,сЬаг *вег2) ( сЬаг оисвсг[всг1еп(всг1] + всг1еп(всг2) + 2] ( вегсру(оиевег,еег1)г всгсас(оисвсг," ")г вегсае(оиевег,вег2)г рг1пСЕ("Ъв1п",оиевег)> ) Массив переменной длины может передаваться как аргумент, как это показано в следующем примере: то1д Е111аггау(апе 1епдСЬ,оЬаг 1еееегв[1епдСЬ)) ( 1пс 12 оЬаг оЬагассег = 'а'г дог([=ог 1<1епдСЬг 1++) 1еееегв[1] = оЬагаоеег++я ) Порядок аргументов может быть обращен благодаря выполнению упреждающего объявления таким образом, что тип 1епдсь известен к тому времени, когда читается массив 1ессегв, что показано в следующем примере: то1д Е111аггау ([пе 1епдСЬ; оЬаг 1еееегв[1епдСЬ), 1пе 1епдСЬ] Вы можете иметь столько подобных упреждающих объявлений, сколько вам нужно (разделенных запятыми илн точкой с запятой; после последнего из них должна стоять точка с запятой).
Глава 4. Компиляция программ на языке С 87 Массивы нулевой длины (Аггауз оФ Еего Еепяй) Имеется расширене С>[>) [) языка С, которое допускает объявление массивов нулевой длины, что обеспечивает создание структур с переменной длиной. Это имеет смысл только в том случае, когда массив нулевой длины объявляется как последний член структуры (з(гпс(). Размер массива может назначаться простым резервированием необходимой под него памяти.
Этот способ демонстрируется в следующей программе: /* хаггау.с ° / 41пс1и((е <всдьо.Ь> еуредек вегисе [ 1пс в1хе/ сЬаг всг1пд[О)( ) ч1еп; 1пс аа1п(1пс агдс,сЬаг *агдч[)) ( ьпс 1/ апе соипг = 22; сЬаг 1еггег = 'а'/ ч1еп *11пе = (ч1еп *)аа11ос(вахеот(ч1еп) + соипс) 11пе->в1хе = соипг( Еог(1=0; 1<соиле/ 1++) 11пе->вегапд[1) = 1ессег++( рг[пее("вахеот(ч1еп)=ь<[1п",в1хеог(ч1еп)]( Еог(1=0/ 1<11пе->взхе; 1++) рг1пет(мас ",11пе->всг1пд[1))( рг1пгк("1п")( гегигп[О)/ ) В м примере ста дартная функция ргапсй () вывоДит значение 4 потомУ что оператор в1геоб ( ) может определить только размер типа Ые объявленного поля структуры.
Вывод программы хаггау выглядит примерно так; в1хеок(ч1еп) 4 а Ь с О е к д Ь 1 З К 1 а и о р д г в Е и ч То же самое может быть достигнуто и определением массива как неполного типа. Этот подход имеет не только преимущество стандартного способа языка С, но также он может использоваться таким же способом, как и массив в предыдущем примере. Дополнительное преимушество состоит в том, что массив может быть определен в инициализаторах. В этом примере размер массива устанавливается равным четырем буквенным символам: /< ьпсаггау.с */ 41пс1и<те <вс<т[о.Ь> суре<[ее вегасе ( 1пс взхе/ слаг всг1пд[); 88 Часть В.
Использование Сборного Компилятора ) ч1еп; ч1еп 1п1гч1еп = ( 4, ( 'а', 'Ь', 'с', '6' 1пг ав1п(1пе вгдс,съаг *агдч()) ( апг 1; рг1пгг("в1хеог(ч1еп)=ЪДХп",взхеог(ч1еп))( рг1пгг("взхеог(1п1еч1еп)=за(Хп",в1хеог(1пзеч1еп))( Еог(1 О[ 1<1п1гч1еп.в1хеу 1++) рг1пег("Ъс ",1п1еч1еп.всг1пд(1))у ргзпгг("Хп")ю гесигп(0)( ) Далее приводится вывод этой программы: в1хеог[ч1еп) 4 в1хеог(1пзсч1еп)=4 а Ь с о Атрибуты (АМЬи1еь) Ключевое слово всег1Ьиее может использоваться для назначения атрибутов при объявлении функций или данных. Основной целью назначения атрибутов является предоставление компилятору возможности выполнения оптимизации.
Атрибуты функции назначаются в объявлении прототипа, как в следующем примере: чозо Яагв1 ехтог() асег1Ьисе ((погесигп)) чоьд гасв1 еггог(сивг еаевваде) ( Ерг1пге(ве[(егг, Чатаъ ВВВОВ: ЪвХп",аевваде) ( ех1Е(1)ю ) В этом примере атрибут погееигп сообщает компилятору, что эта функция не возвращает управление вызывающей ее структуре.
Благодаря этому обычно вставляемый код возврата из функции будет пропущен при оптимизации. В одном объявлении может быть назначено несколько атрибутов. Онн помещаются в список (через запятую). В следующем примере объявление функции назначает атрибуты, сообщающие компилятору что эта функция не изменяет глобальных переменных и что она не должна в дальнейшем подстанавливаться глйпе. апг дег11аО вггг1Ьиге ((риге,по1о11пе))[ Атрибуты могут назначаться отдельно переменным и полям структур. Например, чтобы гарантировать определенное выравнивание поля внутри структуры, его можно объявить следующим образом: вггисе вопд ( сваг 1стю Глава 4.
Компиляция программ на языке С 89 1пс себе ) аССг1Ьике ((а11яп(4))) Таблица 4.3. Атрибуты, используемые при объявлении функций Объявление функции с этим атрибутом приводит к тому что зто объявление становится неприоритетной альтернативой (веех айаэ) другой функции. Для этого он может применяться в сочетании с атрибутом иввк, как в следующем примере, где функция сеисои() создается как альтернатива для сеисои(): а11вв ]ис сессии() ( гесиги(100) г ) чосв сеисои() вссг1ьисе ((нва]с,а1].вв(" сеисои")))> В языке С++ при объявлении основной функции должно быть также указано имя ее заменяющей (гпапл!ед пагпе о((ле (агле().