Spec-Zone.ru › GCC 4

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-enums заставляет GCC генерировать код, который не бинарно совместим с кодом, сгенерированным без этого ключа. Используйте его для соответствия нестандартному интерфейсу приложений.

-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
Генерировать позиционно-независимый код (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, но сгенерированный позиционно-независимый код может быть связан только в исполняемые файлы. Обычно эти параметры используются при использовании опции -pie GCC во время компоновки.

-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.

Проверка стека старого стиля — это общий механизм, который не требует специальной поддержки целевой платформы в компиляторе, но имеет следующие недостатки:

  1. Изменённая стратегия выделения для больших объектов: они всегда выделяются динамически, если их размер превышает фиксированный порог.
  2. Фиксированное ограничение на размер статического кадра функций: когда он достигает определённой функции, проверка стека не надёжна, и компилятор выводит предупреждение.
  3. Неэффективность: из-за изменённой стратегии выделения и общей реализации производительность кода снижается.

Обратите внимание, что проверка стека старого стиля также является резервным методом для 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API