3.18 Варианты конвенций генерации кода
Эти независимые от машины варианты управляют конвенциями интерфейса, используемыми при генерации кода.
Большинство из них имеют как положительную, так и отрицательную формы; отрицательная форма -ffoo — это -fno-foo. В таблице ниже указана только одна форма — та, которая не является стандартной. Вы можете определить другую форму, либо удалив ‘no-’, либо добавив ее.
-fbounds-check- Для front-эндов, которые его поддерживают, генерируется дополнительный код для проверки того, что индексы, используемые для доступа к массивам, находятся в объявленном диапазоне. В настоящее время это поддерживается только Java и Fortran front-эндами, где этот параметр по умолчанию равен true и false соответственно.
-
-fstack-reuse=reuse-level - Этот параметр контролирует повторное использование стекового пространства для объявленных пользователем локальных/автоматических переменных и временных объектов, сгенерированных компилятором. reuse_level может быть ‘
all’, ‘named_vars’ или ‘none’. ‘all’ включает повторное использование стека для всех локальных переменных и временных объектов, ‘named_vars’ включает повторное использование только для определенных пользователем локальных переменных с именами, а ‘none’ полностью отключает повторное использование стека. Значение по умолчанию — ‘all’. Этот параметр необходим, когда программа расширяет срок существования локальной переменной области видимости или временного объекта, сгенерированного компилятором, за пределы точки, определенной языком. Когда срок существования переменной заканчивается, и если переменная находится в памяти, оптимизирующий компилятор имеет право повторно использовать её стековое пространство с другими временными объектами или локальными переменными области видимости, диапазон жизни которых не пересекается с ней. Код, расширяющий срок существования локальных переменных, скорее всего, будет нарушен оптимизацией повторного использования стека.Например,
int *p; { int local1; p = &local1; local1 = 10; .... } { int local2; local2 = 20; ... } if (*p == 10) // out of scope use of local1 { }Другой пример:
struct A { A(int k) : i(k), j(k) { } int i; int j; }; A *ap; void foo(const A& ar) { ap = &ar; } void bar() { foo(A(10)); // temp object's lifetime ends when foo returns { A a(20); .... } ap->i+= 10; // ap references out of scope temp whose space // is reused with a. What is the value of ap->i? }Срок существования временного объекта, сгенерированного компилятором, чётко определён стандартом C++. Когда срок существования временного объекта заканчивается, и если временный объект находится в памяти, оптимизирующий компилятор имеет право повторно использовать его стековое пространство с другими временными объектами или локальными переменными области видимости, диапазон жизни которых не пересекается с ним. Однако некоторые из старых кодов полагаются на поведение более старых компиляторов, в которых стековое пространство временных объектов не повторно использовалось; агрессивное повторное использование стека может привести к ошибкам во время выполнения. Этот параметр используется для управления оптимизацией повторного использования стека временных объектов.
-ftrapv- Этот параметр генерирует ловушки для переполнения знакового результата при операциях сложения, вычитания и умножения.
-fwrapv- Этот параметр указывает компилятору предположить, что знаковое переполнение при сложении, вычитании и умножении обнуляется с использованием представления со знаком дополнения до двух. Этот флаг включает некоторые оптимизации и отключает другие. Этот параметр включён по умолчанию для Java front-энда, как требуется спецификацией языка Java.
-fexceptions- Включить обработку исключений. Генерирует дополнительный код, необходимый для распространения исключений. Для некоторых целей это подразумевает, что GCC генерирует информацию о разматывании стека для всех функций, что может привести к значительному увеличению размера данных, хотя не влияет на выполнение. Если вы не указываете этот параметр, GCC включает его по умолчанию для языков, таких как C++, которые обычно требуют обработки исключений, и отключает его для языков, таких как C, которые обычно её не требуют. Однако вам может потребоваться включить этот параметр при компиляции кода C, который должен корректно взаимодействовать с обработчиками исключений, написанными на C++. Вы также можете отключить этот параметр, если вы компилируете более старые программы C++, которые не используют обработку исключений.
-fnon-call-exceptions- Генерировать код, который позволяет инструкциям отладки выбрасывать исключения. Обратите внимание, что это требует платформенно-специфической поддержки во время выполнения, которая не существует повсюду. Кроме того, это позволяет инструкциям ловушки выбрасывать исключения, т.е. обращения к памяти или инструкции с плавающей запятой. Это не позволяет выбрасывать исключения из произвольных обработчиков сигналов, таких как
SIGALRM. -fdelete-dead-exceptions- Учитывать, что инструкции, которые могут выбросить исключения, но иначе не влияют на выполнение программы, могут быть оптимизированы. Этот параметр включён по умолчанию для Ada front-энда, как разрешено спецификацией языка Ada. Процессы оптимизации, которые приводят к удалению мёртвых исключений, включаются независимо на разных уровнях оптимизации.
-funwind-tables- Аналогично
-fexceptions, за исключением того, что он просто генерирует любые необходимые статические данные, но не влияет на сгенерированный код каким-либо иным образом. Обычно вам не нужно включать этот параметр; вместо этого процессор языка, которому нужна такая обработка, включает его от вашего имени. -fasynchronous-unwind-tables- Генерировать таблицу размотки в формате DWARF 2, если это поддерживается целевой машиной. Таблица точна в каждой точке инструкции, поэтому она может использоваться для размотки стека от асинхронных событий (например, отладчика или сборщика мусора).
-fno-gnu-unique- В системах с последними GNU ассемблером и библиотекой C, C++ компилятор использует привязку
STB_GNU_UNIQUE, чтобы убедиться, что определения статических членов шаблонов и статических локальных переменных в инлайновых функциях уникальны, даже при наличииRTLD_LOCAL; это необходимо для предотвращения проблем с библиотекой, используемой двумя разнымиRTLD_LOCALплагинами, зависящими от определения в одном из них и, следовательно, не соглашаясь с другим относительно привязки символа. Но это приводит к тому, чтоdlcloseигнорируется для затронутых DSO; если ваша программа полагается на перезагрузку DSO с помощьюdlcloseиdlopen, вы можете использовать-fno-gnu-unique. -fpcc-struct-return- Возвращать значения типа “short”
structиunionв памяти, как более длинные, а не в регистрах. Эта конвенция менее эффективна, но имеет преимущество в разрешении взаимозаменяемости между файлами, скомпилированными GCC, и файлами, скомпилированными с другими компиляторами, особенно Portable C Compiler (pcc).Точная конвенция для возврата структур в памяти зависит от макросов конфигурации целевой платформы.
Короткие структуры и объединения — это те, размер и выравнивание которых соответствуют какому-либо целочисленному типу.
Предупреждение: код, скомпилированный с ключом
-fpcc-struct-returnне бинарно совместим с кодом, скомпилированным с ключом-freg-struct-return. Используйте его для соответствия нестандартному интерфейсу приложений. -freg-struct-return- Возвращать значения
structиunionв регистрах, когда это возможно. Это более эффективно для небольших структур, чем-fpcc-struct-return.Если вы не укажете ни
-fpcc-struct-return, ни-freg-struct-return, GCC по умолчанию использует ту конвенцию, которая является стандартной для целевой платформы. Если стандартной конвенции нет, GCC по умолчанию использует-fpcc-struct-return, за исключением платформ, где GCC является основным компилятором. В таких случаях мы можем выбрать стандарт, и мы выбрали более эффективную альтернативу возврата в регистре.Предупреждение: код, скомпилированный с ключом
-freg-struct-returnне бинарно совместим с кодом, скомпилированным с ключом-fpcc-struct-return. Используйте его для соответствия нестандартному интерфейсу приложений. -fshort-enums- Выделить типу
enumтолько столько байтов, сколько необходимо для объявленного диапазона возможных значений. В частности, типenumэквивалентен наименьшему целочисленному типу, который имеет достаточно места. -fshort-double- Использовать тот же размер для
doubleчто и дляfloat.Предупреждение: ключ
-fshort-doubleзаставляет GCC генерировать код, который не бинарно совместим с кодом, сгенерированным без этого ключа. Используйте его для соответствия нестандартному интерфейсу приложений. -fshort-wchar- Переопределить базовый тип для ‘
wchar_t’ на ‘short unsigned int’ вместо значения по умолчанию для целевой платформы. Этот параметр полезен для создания программ, которые будут работать под WINE.Предупреждение: ключ
-fshort-wcharзаставляет GCC генерировать код, который не бинарно совместим с кодом, сгенерированным без этого ключа. Используйте его для соответствия нестандартному интерфейсу приложений. -fno-common- В коде C, управляет размещением неинициализированных глобальных переменных. Компиляторы Unix C традиционно разрешали несколько определений таких переменных в разных единицах компиляции, размещая переменные в общей области. Это поведение задается
-fcommon, и это по умолчанию для GCC на большинстве целевых платформ. С другой стороны, это поведение не требуется стандартом ISO C, и на некоторых платформах может привести к снижению скорости или увеличению размера кода при обращениях к переменным. Параметр-fno-commonуказывает компилятору разместить неинициализированные глобальные переменные в секции данных объектного файла, а не генерировать их как общие блоки. Это означает, что если одна и та же переменная объявлена (безextern) в двух разных компиляциях, при их компоновке вы получите ошибку множественного определения. В этом случае необходимо скомпилировать с-fcommon. Компиляция с-fno-commonполезна на целевых платформах, для которых это обеспечивает лучшую производительность, или если вы хотите проверить, что программа будет работать на других системах, которые всегда обрабатывают объявления неинициализированных переменных таким образом. -fno-ident- Игнорировать директиву ‘
#ident’. -finhibit-size-directive- Не выводить директиву ассемблера
.size, или что-либо ещё, что могло бы вызвать проблемы, если функция разделена пополам, и обе половины размещены в разных местах памяти. Этот параметр используется при компиляцииcrtstuff.c; вы не должны использовать его для чего-либо ещё. -fverbose-asm- Вставлять дополнительную информацию в сгенерированный код ассемблера, чтобы сделать его более читабельным. Этот параметр, как правило, полезен только тем, кому нужно читать сгенерированный код ассемблера (возможно, во время отладки самого компилятора).
-fno-verbose-asm, значение по умолчанию, приводит к тому, что дополнительная информация опускается, и это полезно при сравнении двух файлов ассемблера. -frecord-gcc-switches- Этот ключ заставляет компилятор записывать командную строку, используемую для вызова компилятора, в создаваемый объектный файл. Этот ключ реализован только на некоторых платформах, и точный формат записи зависит от платформы и формата двоичного файла, но обычно он принимает вид секции, содержащей текст ASCII. Этот ключ связан с ключом
-fverbose-asm, но этот ключ записывает информацию только в файл ассемблера в виде комментариев, поэтому он никогда не достигает объектного файла. См. также-grecord-gcc-switchesдля другого способа хранения параметров компилятора в объектный файл. -fpic
Предупреждение: ключ -fshort-enums заставляет GCC генерировать код, который не бинарно совместим с кодом, сгенерированным без этого ключа. Используйте его для соответствия нестандартному интерфейсу приложений.
- Генерировать позиционно-независимый код (PIC), пригодный для использования в общей библиотеке, если это поддерживается для целевой машины. Такой код обращается ко всем постоянным адресам через таблицу глобальных смещений (GOT). Динамический загрузчик разрешает записи GOT при запуске программы (динамический загрузчик не является частью GCC; он является частью операционной системы). Если размер GOT для связанного исполняемого файла превышает машинозависимый максимальный размер, вы получите сообщение об ошибке от компоновщика, указывающее, что
-fpicне работает; в этом случае перекомпилируйте с-fPICвместо этого. (Эти максимальные значения составляют 8 КБ на SPARC и 32 КБ на m68k и RS/6000. У 386 нет такого ограничения.)Позиционно-независимый код требует специальной поддержки и, следовательно, работает только на определённых машинах. Для 386 GCC поддерживает PIC для System V, но не для Sun 386i. Код, сгенерированный для IBM RS/6000, всегда позиционно-независимый.
При установке этого флага макросы
__pic__и__PIC__определяются как 1. -fPIC- Если это поддерживается для целевой машины, генерировать позиционно-независимый код, подходящий для динамической компоновки и избегания каких-либо ограничений на размер таблицы глобальных смещений. Этот параметр имеет значение на m68k, PowerPC и SPARC.
Позиционно-независимый код требует специальной поддержки и, следовательно, работает только на определённых машинах.
При установке этого флага макросы
__pic__и__PIC__определяются как 2. -
-fpie-fPIE - Эти параметры аналогичны
-fpicи-fPIC, но сгенерированный позиционно-независимый код может быть связан только в исполняемые файлы. Обычно эти параметры используются при использовании опции-pieGCC во время компоновки.-fpieи-fPIEоба определяют макросы__pie__и__PIE__. Макросы имеют значение 1 для-fpieи 2 для-fPIE. -fno-jump-tables- Не использовать таблицы переходов для операторов switch даже в тех случаях, когда это было бы эффективнее, чем другие стратегии генерации кода. Этот параметр полезен в сочетании с
-fpicили-fPICдля построения кода, который является частью динамического загрузчика и не может ссылаться на адрес таблицы переходов. На некоторых целевых платформах таблицы переходов не требуют GOT, и этот параметр не нужен. -
-ffixed-reg - Обрабатывать регистр с именем reg как фиксированный регистр; сгенерированный код никогда не должен ссылаться на него (за исключением, возможно, регистров стека, фрейма или в какой-либо другой фиксированной роли).
reg должно быть именем регистра. Принимаемые имена регистров зависят от машины и определяются в макросе
REGISTER_NAMESв файле макросов описания машины.Этот флаг не имеет отрицательной формы, потому что он определяет трёхсторонний выбор.
-
-fcall-used-reg - Обрабатывать регистр с именем reg как регистр, который может быть выделен и уничтожается вызовами функций. Он может быть выделен для временных переменных или переменных, которые не существуют между вызовами. Функции, скомпилированные таким образом, не сохраняют и не восстанавливают регистр reg.
Ошибка использования этого флага с регистром фрейма или стека. Использование этого флага для других регистров, которые имеют фиксированные распространённые роли в модели выполнения машины, приводит к катастрофическим последствиям.
Этот флаг не имеет отрицательной формы, потому что он определяет трёхсторонний выбор.
-
-fcall-saved-reg - Обрабатывать регистр с именем reg как регистр, который может быть выделен и сохраняется функциями. Он может быть выделен даже для временных переменных или переменных, которые существуют между вызовами. Скомпилированные таким образом функции сохраняют и восстанавливают регистр reg, если они его используют.
Ошибка использования этого флага с регистром фрейма или стека. Использование этого флага для других регистров, которые имеют фиксированные распространённые роли в модели выполнения машины, приводит к катастрофическим последствиям.
Другой вид катастрофы возникает при использовании этого флага для регистра, в котором могут возвращаться значения функций.
Этот флаг не имеет отрицательной формы, потому что он определяет трёхсторонний выбор.
-
-fpack-struct[=n] - Без указанного значения все члены структуры упаковываются вместе без пробелов. При указании значения (которое должно быть небольшой степенью двойки), члены структуры упаковываются в соответствии с этим значением, представляющим максимальное выравнивание (то есть объекты с требованиями к выравниванию по умолчанию, большими, чем это, выводятся, возможно, невыровненными в следующем подходящем месте.
Предупреждение: переключатель
-fpack-structзаставляет GCC генерировать код, который не является двоично совместимым с кодом, сгенерированным без этого переключателя. Кроме того, это делает код не оптимальным. Используйте его для соответствия нестандартному интерфейсу приложений. -finstrument-functions- Генерировать вызовы инструментов для входа и выхода из функций. Сразу после входа в функцию и перед выходом из функции вызываются следующие профилирующие функции с адресом текущей функции и её места вызова. (На некоторых платформах
__builtin_return_addressне работает за пределами текущей функции, поэтому информация о месте вызова может быть недоступна профилирующим функциям в противном случае.)void __cyg_profile_func_enter (void *this_fn, void *call_site); void __cyg_profile_func_exit (void *this_fn, void *call_site);Первый аргумент — адрес начала текущей функции, который можно найти точно в таблице символов.
Эта инструментация также выполняется для функций, развернутых встраиваемо в другие функции. Профилирующие вызовы указывают, где концептуально встраиваемая функция входит и выходит. Это означает, что должны быть доступны адресованные версии таких функций. Если все ваши использования функции развернуты встроенно, это может означать дополнительное увеличение размера кода. Если вы используете «
extern inline» в своём коде C, должна быть предоставлена адресовываемая версия таких функций. (Это обычно так и есть, но если вам повезёт, и оптимизатор всегда встраивает функции, вы могли бы обойтись без предоставления статических копий.)Функции могут быть заданы атрибутом
no_instrument_function, в этом случае такая инструментация не выполняется. Это можно использовать, например, для профилирующих функций, указанных выше, высокоприоритетных обработчиков прерываний и любых функций, из которых профилирующие функции не могут быть безопасно вызваны (например, обработчики сигналов, если профилирующие функции генерируют вывод или выделяет память). -
-finstrument-functions-exclude-file-list=file,file,... - Установить список функций, которые исключаются из инструментации (см. описание
-finstrument-functions). Если файл, содержащий определение функции, совпадает с одним из file, то эта функция не инструментируется. Совпадение выполняется по подстрокам: если параметр file является подстрокой имени файла, он считается совпадением.Например:
-finstrument-functions-exclude-file-list=/bits/stl,include/sys
исключает любые встроенные функции, определённые в файлах, имена путей которых содержат
/bits/stlилиinclude/sys.Если по какой-то причине вы хотите включить букву
','в один из sym, напишите'\,'. Например,-finstrument-functions-exclude-file-list='\,\,tmp'(обратите внимание на одинарную кавычку вокруг параметра). -
-finstrument-functions-exclude-function-list=sym,sym,... - Это аналогично
-finstrument-functions-exclude-file-list, но этот параметр устанавливает список имён функций, которые будут исключены из инструментации. Имя функции для сопоставления — это её видимое пользователю имя, такое какvector<int> blah(const vector<int> &), а не внутреннее имя с кодом преобразования (например,_Z4blahRSt6vectorIiSaIiEE). Сопоставление выполняется по подстрокам: если параметр sym является подстрокой имени функции, он считается совпадением. Для идентификаторов C99 и C++, расширенных для C++, имя функции должно быть указано в UTF-8, а не с использованием универсальных символьных имен. -fstack-check- Сгенерировать код для проверки того, что вы не выходите за пределы стека. Вы должны указать этот флаг, если вы работаете в среде с несколькими потоками, но вам редко нужно указывать его в однопотоковой среде, так как переполнение стека автоматически обнаруживается практически на всех системах, если имеется только один стек.
Обратите внимание, что этот переключатель фактически не вызывает проверки; операционная система или среда выполнения языка должны это сделать. Переключатель вызывает генерацию кода, чтобы гарантировать, что они видят расширение стека.
Вы можете дополнительно указать строковый параметр:
noозначает отсутствие проверки,genericозначает принудительное использование проверки старого стиля,specificозначает использование лучшего метода проверки и эквивалентно простому-fstack-check.Проверка стека старого стиля — это общий механизм, который не требует специальной поддержки целевой платформы в компиляторе, но имеет следующие недостатки:
- Изменённая стратегия выделения для больших объектов: они всегда выделяются динамически, если их размер превышает фиксированный порог.
- Фиксированное ограничение на размер статического кадра функций: когда он достигает определённой функции, проверка стека не надёжна, и компилятор выводит предупреждение.
- Неэффективность: из-за изменённой стратегии выделения и общей реализации производительность кода снижается.
Обратите внимание, что проверка стека старого стиля также является резервным методом для
specificв случае отсутствия поддержки целевой платформы в компиляторе. -
-fstack-limit-register=reg-fstack-limit-symbol=sym-fno-stack-limit - Генерировать код для обеспечения того, что стек не вырастет за определённое значение, либо значение регистра, либо адрес символа. Если требуется больший стек, во время выполнения генерируется сигнал. Для большинства целевых платформ сигнал генерируется до того, как стек переполнит границу, поэтому можно перехватить сигнал, не принимая особых мер предосторожности.
Например, если стек начинается по абсолютному адресу ‘
0x80000000’ и растёт вниз, вы можете использовать флаги-fstack-limit-symbol=__stack_limitи-Wl,--defsym,__stack_limit=0x7ffe0000для задания предела стека в 128 КБ. Обратите внимание, что это может работать только с GNU компоновщиком. -fsplit-stack
- Генерировать код для автоматического разделения стека перед его переполнением. Полученная программа имеет разрозненный стек, который может переполниться только в том случае, если программа не может выделить больше памяти. Это наиболее полезно при выполнении многопоточных программ, так как теперь нет необходимости рассчитывать подходящий размер стека для каждого потока. В настоящее время это реализовано только для бэкендов i386 и x86_64 под GNU/Linux.
Когда код, скомпилированный с
-fsplit-stack, вызывает код, скомпилированный без-fsplit-stack, для последнего кода может быть доступно немного места в стеке. Если компиляция всего кода, включая код библиотек, с-fsplit-stackневозможна, тогда компоновщик может исправить эти вызовы так, чтобы код, скомпилированный без-fsplit-stack, всегда имел большой стек. Поддержка этой функции реализована в компоновщике gold в выпуске GNU binutils 2.21 и более поздних версиях. -fleading-underscore- Этот параметр и его аналог
-fno-leading-underscoreпринудительно изменяют способ представления символов C в объектном файле. Одно из применений — помощь при линковке с устаревшим ассемблерным кодом.Предупреждение: переключатель
-fleading-underscoreзаставляет GCC генерировать код, который не совместим с двоичным кодом, сгенерированным без этого переключателя. Используйте его для соответствия нестандартному прикладному двоичному интерфейсу. Не все целевые платформы полностью поддерживают этот переключатель. -
-ftls-model=model - Изменить модель локального хранения потоков (см. Локальное хранение потоков). Аргумент model должен быть одним из
global-dynamic,local-dynamic,initial-execилиlocal-exec. Обратите внимание, что выбор зависит от оптимизации: компилятор может использовать более эффективную модель для символов, не видимых за пределами трансляционной единицы, или если-fpicне указан в командной строке.По умолчанию без
-fpicиспользуетсяinitial-exec; с-fpicпо умолчанию используетсяglobal-dynamic. -
-fvisibility=default|internal|hidden|protected - Установить видимость символов изображения ELF по умолчанию на указанное значение — все символы помечаются этим значением, если не переопределено в коде. Использование этой функции может существенно улучшить время линковки и загрузки библиотек динамической загрузки, создать более оптимизированный код, обеспечить практически идеальный экспорт API и предотвратить столкновения символов. Настоятельно рекомендуется использовать ее во всех распространяемых вами библиотеках динамической загрузки.
Несмотря на наименование,
defaultвсегда означает общедоступность; то есть доступно для линковки извне библиотеки динамической загрузки.protectedиinternalпрактически бесполезны в реальном использовании, поэтому единственный другой часто используемый параметр —hidden. По умолчанию, если-fvisibilityне указан, используетсяdefault, т. е. делает каждый символ общедоступным — это вызывает такое же поведение, как и в предыдущих версиях GCC.Хорошее объяснение преимуществ обеспечения правильной видимости символов ELF содержится в статье «Как создавать библиотеки динамической загрузки» Ульриха Дреппера (которую можно найти по адресу http://people.redhat.com/~drepper/) — однако лучшее решение, достигаемое с помощью этого параметра для маркировки скрытых элементов, когда значение по умолчанию — общедоступное, — сделать значение по умолчанию скрытым и отмечать элементы как общедоступные. Это стандарт для DLL на Windows и с использованием
-fvisibility=hiddenи__attribute__ ((visibility("default")))вместо__declspec(dllexport)вы получите практически идентичные семантику и синтаксис. Это большая польза для тех, кто работает с кроссплатформенными проектами.Для тех, кто добавляет поддержку видимости в существующий код, может быть полезно ‘
#pragma GCC visibility’. Это работает, заключая объявления, для которых вы хотите установить видимость, в (например) ‘#pragma GCC visibility push(hidden)’ и ‘#pragma GCC visibility pop’. Помните, что видимость символов следует рассматривать как часть контракта интерфейса API, и поэтому весь новый код должен всегда указывать видимость, когда она не является значением по умолчанию; т. е. объявления, предназначенные только для использования внутри локального DSO, всегда должны быть явными скрытыми, чтобы избежать накладных расходов на косвенные ссылки PLT — ясность этого также способствует читаемости и самодокументированию кода. Обратите внимание, что из-за требований спецификации ISO C++,operator newиoperator deleteвсегда должны иметь видимость по умолчанию.Обратите внимание, что заголовки извне вашего проекта, особенно системные заголовки и заголовки из любой используемой вами библиотеки, могут не ожидать компиляции с видимостью, отличной от значения по умолчанию. Возможно, вам потребуется явно указать ‘
#pragma GCC visibility push(default)’ перед включением таких заголовков.Объявления ‘
extern’ не затрагиваются-fvisibility, поэтому большая часть кода может быть перекомпилирована с-fvisibility=hiddenбез изменений. Однако это означает, что вызовы функцийexternбез явной видимости используют PLT, поэтому эффективнее использовать__attribute ((visibility))и/или#pragma GCC visibilityдля указания компилятору, какие объявленияexternследует рассматривать как скрытые.Обратите внимание, что
-fvisibilityвлияет на сущности неявной линковки C++. Это означает, что, например, класс исключения, который будет выброшен между DSO, должен быть явно помечен видимостью по умолчанию, чтобы узлы «type_info» были объединены между DSO.Обзор этих техник, их преимуществ и способов их использования см. по адресу http://gcc.gnu.org/wiki/Visibility.
-fstrict-volatile-bitfields- Этот параметр следует использовать, если доступ к переменным volatile bit-fields (или другим полям структуры, хотя компилятор обычно поддерживает эти типы) должен использовать единственный доступ шириной типа поля, выровненный по естественному выравниванию, если это возможно. Например, целевые платформы с периферийными регистрами, отображенными в памяти, могут потребовать, чтобы все такие обращения имели ширину 16 бит; с этим флагом вы можете объявить все поля bit-fields периферийных устройств как
unsigned short(при условии, что short составляет 16 бит на этих платформах) для принудительного использования 16-битных обращений вместо, возможно, более эффективного 32-битного доступа.Если этот параметр отключен, компилятор использует наиболее эффективный код. В приведенном выше примере это может быть инструкция загрузки 32 бит, даже если она обращается к байтам, не содержащим какой-либо части bit-field, или к регистрам отображения в памяти, не связанным с обновляемым регистром.
В некоторых случаях, например, когда атрибут
packedприменяется к полю структуры, доступ к полю может быть невозможен с помощью одного чтения или записи, правильно выровненного для целевой машины. В этом случае GCC переходит к генерации нескольких обращений вместо кода, который вызовет ошибку или обрубит результат во время выполнения.Примечание: из-за ограничений модели памяти C/C++11 обращения записи не разрешено затрагивать не являющиеся bit-field элементы. Поэтому рекомендуется определять все биты типа поля как члены bit-field.
Значение этого параметра по умолчанию определяется прикладным двоичным интерфейсом целевого процессора.
-fsync-libcalls- Этот параметр управляет тем, могут ли быть использованы любые внестрочные экземпляры функций семейства
__syncдля реализации функций семейства C++11__atomic.Значение этого параметра по умолчанию включено, поэтому единственная полезная форма параметра —
-fno-sync-libcalls. Этот параметр используется в реализации библиотеки времени выполненияlibatomic.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Code-Gen-Options.html