Spec-Zone.ru › GCC 14

3.17 Параметры соглашений о генерации кода

Эти независимые от машины параметры управляют соглашениями интерфейса, используемыми при генерации кода.

Большинство из них имеют положительную и отрицательную формы; отрицательная форма -ffoo — это -fno-foo. В таблице ниже приведена только одна форма — та, которая не является стандартной. Вы можете определить другую форму, либо удалив «no-», либо добавив её.

-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

Этот параметр генерирует ловушки (traps) для переполнения при сложении, вычитании и умножении со знаком. Параметры -ftrapv и -fwrapv перекрывают друг друга, поэтому использование -ftrapv -fwrapv в командной строке приводит к тому, что эффективным является -fwrapv. Обратите внимание, что только активные параметры перекрывают, поэтому использование -ftrapv -fwrapv -fno-wrapv в командной строке приводит к тому, что эффективным является -ftrapv.

-fwrapv

Этот параметр указывает компилятору предположить, что переполнение при арифметических операциях со знаком сложения, вычитания и умножения происходит с обходом (wraps around) с использованием представления со знаком дополнения до двух. Этот флаг включает некоторые оптимизации и отключает другие. Параметры -ftrapv и -fwrapv перекрывают друг друга, поэтому использование -ftrapv -fwrapv в командной строке приводит к тому, что эффективным является -fwrapv. Обратите внимание, что только активные параметры перекрывают, поэтому использование -ftrapv -fwrapv -fno-wrapv в командной строке приводит к тому, что эффективным является -ftrapv.

-fwrapv-pointer

Этот параметр указывает компилятору предположить, что переполнение при арифметике указателей при сложении и вычитании происходит с обходом (wraps around) с использованием представления со знаком дополнения до двух. Этот флаг отключает некоторые оптимизации, которые предполагают, что переполнение указателей недопустимо.

-fstrict-overflow

Этот параметр подразумевает -fno-wrapv -fno-wrapv-pointer и при отрицании подразумевает -fwrapv -fwrapv-pointer.

-fexceptions

Включает обработку исключений. Генерирует дополнительный код, необходимый для распространения исключений. Для некоторых целевых платформ это подразумевает, что GCC генерирует информацию о разматывании стека (frame unwind) для всех функций, что может привести к значительному увеличению размера данных, хотя не влияет на выполнение. Если вы не укажете этот параметр, GCC включит его по умолчанию для языков, таких как C++, которые обычно требуют обработки исключений, и отключит его для языков, таких как C, которые обычно её не требуют. Однако вам может потребоваться включить этот параметр при компиляции кода C, который должен правильно взаимодействовать с обработчиками исключений, написанными на C++. Вы также можете отключить этот параметр, если вы компилируете старые программы C++, которые не используют обработку исключений.

-fnon-call-exceptions

Генерирует код, позволяющий инструкциям ловушки (trapping instructions) выбрасывать исключения. Обратите внимание, что для этого требуется поддержка платформенного времени выполнения, которая не существует везде. Кроме того, он позволяет выбрасывать исключения только инструкциям ловушки (trapping instructions), то есть инструкциям обращения к памяти или инструкциям работы с плавающей точкой. Он не позволяет выбрасывать исключения из произвольных обработчиков сигналов, таких как SIGALRM. Это включает -fexceptions.

-fdelete-dead-exceptions

Учитывается, что инструкции, которые могут вызывать исключения, но не вносят никакого иного вклада в выполнение программы, могут быть оптимизированы. Это не затрагивает вызовы функций, за исключением тех, у которых есть атрибуты pure или const. Этот параметр включён по умолчанию для компиляторов Ada и C++, как разрешено спецификациями языка. Проходы оптимизации, которые приводят к удалению мёртвых исключений, включаются независимо на различных уровнях оптимизации.

-funwind-tables

Аналогично -fexceptions, за исключением того, что он просто генерирует любые необходимые статические данные, но не влияет на сгенерированный код каким-либо другим способом. Обычно вам не нужно включать этот параметр; вместо этого процессор языка, которому требуется такая обработка, включает его от вашего имени.

-fasynchronous-unwind-tables

Генерирует таблицу разматывания стека в формате DWARF, если это поддерживается целевой машиной. Таблица является точной на границе каждой инструкции, поэтому её можно использовать для разматывания стека из асинхронных событий (таких как отладчик или сборщик мусора).

-fno-gnu-unique

На системах с недавними GNU ассемблером и библиотекой C, компилятор C++ использует привязку STB_GNU_UNIQUE, чтобы убедиться, что определения шаблонов статических данных членов и статических локальных переменных во встроенных функциях уникальны даже при наличии RTLD_LOCAL; это необходимо, чтобы избежать проблем с библиотекой, используемой двумя разными RTLD_LOCAL плагинами, которые зависят от определения в одном из них и, следовательно, не соглашаются с другим относительно привязки символа. Но это приводит к тому, что dlclose игнорируется для затронутых DSO; если ваша программа полагается на повторную инициализацию DSO через dlclose и dlopen, вы можете использовать -fno-gnu-unique.

-fpcc-struct-return

Возвращать «короткие» 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-wchar

Переопределить базовый тип для wchar_t на short unsigned int вместо значения по умолчанию для целевой платформы. Этот параметр полезен для построения программ для работы под WINE.

Предупреждение: параметр -fshort-wchar заставляет GCC генерировать код, который не является бинарно совместимым с кодом, сгенерированным без этого параметра. Используйте его для соответствия нестандартному интерфейсу приложения.

-fcommon

В коде C этот параметр управляет размещением глобальных переменных, определённых без инициализатора, известных как пробные определения (tentative definitions) в стандарте C. Пробные определения отличаются от объявлений переменной с ключевым словом extern, которые не выделяют памяти.

Значение по умолчанию — -fno-common, которое указывает компилятору разместить неинициализированные глобальные переменные в разделе BSS объектного файла. Это препятствует объединению пробных определений линковщиком, поэтому вы получите ошибку множественного определения, если одна и та же переменная случайно определена в нескольких единицах компиляции.

Параметр -fcommon размещает неинициализированные глобальные переменные в общем блоке (common block). Это позволяет линковщику объединить все пробные определения одной и той же переменной в разных единицах компиляции в один объект или в не-пробное определение. Это поведение не согласуется с C++, и на многих платформах подразумевает снижение скорости и увеличение размера кода при обращении к глобальным переменным. Оно в основном полезно для поддержки старого кода, чтобы позволить ему линковаться без ошибок.

-fno-ident

Игнорировать директиву #ident.

-finhibit-size-directive

Не выводить директиву .size ассемблера или что-либо ещё, что может вызвать проблемы, если функция разделена пополам, а две половины размещены в разных местах памяти. Этот параметр используется при компиляции crtstuff.c; вам не нужно его использовать для чего-то другого.

-fverbose-asm

Вставлять дополнительные комментарии в сгенерированный ассемблерный код, чтобы сделать его более читаемым. Этот параметр, как правило, полезен только тем, кому действительно нужно прочитать сгенерированный ассемблерный код (например, во время отладки самого компилятора).

-fno-verbose-asm, по умолчанию, приводит к опущению дополнительной информации и полезен при сравнении двух ассемблерных файлов.

Добавленные комментарии включают:

  • информацию о версии компилятора и параметрах командной строки,
  • строки исходного кода, связанные с ассемблерными инструкциями, в формате ИМЯ_ФАЙЛА:НОМЕР_СТРОКИ:СОДЕРЖИМОЕ_СТРОКИ,
  • подсказки о том, какие выражения высокого уровня соответствуют различным операндам ассемблерных инструкций.

Например, для данного файла исходного кода C:

int test (int n)
{
  int i;
  int total = 0;

  for (i = 0; i < n; i++)
    total += i * i;

  return total;
}

компиляция в ассемблерный код (x86_64) с помощью -S и вывод результата напрямую в стандартный вывод с помощью -o -

gcc -S test.c -fverbose-asm -Os -o -

дает вывод, аналогичный этому:

.file	"test.c"
# GNU C11 (GCC) version 7.0.0 20160809 (experimental) (x86_64-pc-linux-gnu)
  [...snip...]
# options passed:
  [...snip...]

	.text
	.globl	test
	.type	test, @function
test:
.LFB0:
	.cfi_startproc
# test.c:4:   int total = 0;
	xorl	%eax, %eax	# <retval>
# test.c:6:   for (i = 0; i < n; i++)
	xorl	%edx, %edx	# i
.L2:
# test.c:6:   for (i = 0; i < n; i++)
	cmpl	%edi, %edx	# n, i
	jge	.L5	#,
# test.c:7:     total += i * i;
	movl	%edx, %ecx	# i, tmp92
	imull	%edx, %ecx	# i, tmp92
# test.c:6:   for (i = 0; i < n; i++)
	incl	%edx	# i
# test.c:7:     total += i * i;
	addl	%ecx, %eax	# tmp92, <retval>
	jmp	.L2	#
.L5:
# test.c:10: }
	ret
	.cfi_endproc
.LFE0:
	.size	test, .-test
	.ident	"GCC: (GNU) 7.0.0 20160809 (experimental)"
	.section	.note.GNU-stack,"",@progbits

Комментарии предназначены для людей, а не для машин, поэтому точный формат комментариев может изменяться.

-frecord-gcc-switches

Этот переключатель записывает командную строку, используемую для вызова компилятора, в создаваемый объектный файл. Этот переключатель реализован только на некоторых целевых платформах, а точный формат записи зависит от целевой платформы и формата двоичного файла, но он обычно имеет вид секции, содержащей текст ASCII. Этот переключатель связан с переключателем -fverbose-asm, но этот переключатель записывает информацию только в ассемблерный файл в виде комментариев, поэтому он никогда не достигает объектного файла. Смотрите также -grecord-gcc-switches для другого способа сохранения параметров компилятора в объектный файл.

-fpic

Генерировать позиционно-независимый код (PIC), подходящий для использования в динамической библиотеке, если это поддерживается целевой машиной. Такой код обращается ко всем константным адресам через глобальную таблицу смещений (GOT). Динамический загрузчик разрешает записи GOT при запуске программы (динамический загрузчик не является частью GCC; он является частью операционной системы). Если размер GOT для связанного исполняемого файла превышает машинно-специфический максимальный размер, вы получите сообщение об ошибке от компоновщика, указывающее, что -fpic не работает; в этом случае перекомпилируйте с -fPIC вместо этого. (Эти максимальные значения составляют 8 КБ на SPARC, 28 КБ на AArch64 и 32 КБ на m68k и RS/6000. У x86 нет такого ограничения.)

Позиционно-независимый код требует специальной поддержки и поэтому работает только на определенных машинах. Для x86 GCC поддерживает PIC для System V, но не для Sun 386i. Код, сгенерированный для IBM RS/6000, всегда позиционно-независим.

Когда этот флаг установлен, макросы __pic__ и __PIC__ определяются как 1.

-fPIC

Если это поддерживается целевой машиной, выводить позиционно-независимый код, подходящий для динамической компоновки и избегающий любого ограничения на размер глобальной таблицы смещений. Этот параметр имеет значение на AArch64, m68k, PowerPC и SPARC.

Позиционно-независимый код требует специальной поддержки и поэтому работает только на определенных машинах.

Когда этот флаг установлен, макросы __pic__ и __PIC__ определяются как 2.

-fpie
-fPIE

Эти параметры аналогичны -fpic и -fPIC, но сгенерированный позиционно-независимый код может быть связан только с исполняемыми файлами. Обычно эти параметры используются для компиляции кода, который будет связан с помощью параметра -pie GCC.

-fpie и -fPIE оба определяют макросы __pie__ и __PIE__. Макросы имеют значение 1 для -fpie и 2 для -fPIE.

-fno-plt

Не использовать PLT для вызовов внешних функций в позиционно-независимом коде. Вместо этого загружать адрес вызываемой функции в местах вызова из GOT и переходить к нему. Это приводит к более эффективному коду за счет устранения PLT-подпрограмм и предоставления оптимизаторам доступа к загрузкам GOT. На таких архитектурах, как 32-разрядный x86, где PLT-подпрограммы ожидают указатель GOT в определенном регистре, это дает компилятору больше свободы при распределении регистров.

Альтернативно, можно использовать атрибут функции noplt, чтобы избежать вызовов через PLT для определенных внешних функций.

В позиционно-зависимом коде несколько целевых платформ также преобразуют вызовы функций, помеченные как не использующие PLT, в использование GOT вместо этого.

-fno-jump-tables

Не использовать таблицы переходов для операторов switch, даже в тех случаях, когда это было бы эффективнее, чем другие стратегии генерации кода. Этот параметр полезен в сочетании с -fpic или -fPIC для построения кода, который является частью динамического загрузчика и не может ссылаться на адрес таблицы переходов.

-fno-bit-tests

Не использовать битовые тесты для операторов switch, даже в тех случаях, когда это было бы эффективнее, чем другие стратегии генерации кода.

-ffixed-reg

Обращаться к регистру с именем reg как к фиксированному регистру; сгенерированный код не должен ссылаться на него (кроме, возможно, стекового указателя, указателя фрейма или в какой-либо другой фиксированной роли).

reg должно быть именем регистра. Допустимые имена регистров зависят от конкретной машины и определены в макросе REGISTER_NAMES в файле макросов описания машины.

Этот флаг не имеет отрицательной формы, потому что он определяет трехсторонний выбор.

-fcall-used-reg

Обращаться к регистру с именем reg как к регистру, который можно выделять и который изменяется вызовами функций. Он может быть выделен для временных переменных или переменных, которые не существуют между вызовами. Функции, скомпилированные таким образом, не сохраняют и не восстанавливают регистр reg.

Использование этого флага с указателем кадра или стека является ошибкой. Использование этого флага для других регистров, имеющих фиксированные распространенные роли в модели выполнения машины, приводит к катастрофическим результатам.

Этот флаг не имеет отрицательной формы, потому что он определяет трехсторонний выбор.

-fcall-saved-reg

Обращаться к регистру с именем reg как к регистру, который можно выделять и который сохраняется функциями. Он может быть выделен даже для временных переменных или переменных, которые существуют между вызовами. Функции, скомпилированные таким образом, сохраняют и восстанавливают регистр reg, если они его используют.

Использование этого флага с указателем фрейма или стека является ошибкой. Использование этого флага для других регистров, имеющих фиксированные распространенные роли в модели выполнения машины, приводит к катастрофическим результатам.

Другой вид катастрофы возникает при использовании этого флага для регистра, в котором могут возвращаться значения функций.

Этот флаг не имеет отрицательной формы, потому что он определяет трехсторонний выбор.

-fpack-struct[=n]

Без указанного значения все члены структуры упаковываются вместе без пробелов. При указании значения (которое должно быть небольшой степенью двойки), члены структуры упаковываются в соответствии с этим значением, представляющим максимальное выравнивание (то есть объекты с требованиями по выравниванию по умолчанию, превышающими это значение, выводятся потенциально невыровненными в следующем подходящем месте).

Предупреждение: переключатель -fpack-struct заставляет GCC генерировать код, не совместимый с двоичным кодом, сгенерированным без этого переключателя. Кроме того, это делает код не оптимальным. Используйте его для соответствия нестандартному интерфейсу приложений.

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

-ftrampolines

Для целей, которые обычно требуют трамплинов для вложенных функций, всегда генерировать их вместо использования дескрипторов. В противном случае, для целей, которые их не нуждаются, например, для HP-PA или IA-64, ничего не делать.

Трамплин — это небольшой фрагмент кода, создаваемый во время выполнения на стеке, когда берется адрес вложенной функции, и используется для косвенного вызова вложенной функции. Поэтому для правильной работы программы требуется, чтобы стек был исполняемым.

-fno-trampolines включен по умолчанию на основе языка, чтобы компилятор избегал их генерации, если считает это безопасным, и заменял их дескрипторами. Дескрипторы состоят только из данных, но сгенерированный код должен быть готов работать с ними. На данный момент -fno-trampolines включен по умолчанию только для Ada.

Кроме того, код, скомпилированный с -ftrampolines и код, скомпилированный с -fno-trampolines, не являются двоично совместимыми, если присутствуют вложенные функции. Поэтому этот параметр должен использоваться на уровне всей программы и с большой осторожностью.

Для языков, отличных от Ada, параметры -ftrampolines и -fno-trampolines в настоящее время не имеют эффекта, и трамплины всегда генерируются на платформах, которые нуждаются в них для вложенных функций.

-ftrampoline-impl=[stack|heap]

По умолчанию трамплины генерируются на стеке. Однако некоторые платформы (например, Apple M1) не допускают исполняемый стек. Компиляция с -ftrampoline-impl=heap генерирует вызовы к __gcc_nested_func_ptr_created и __gcc_nested_func_ptr_deleted для выделения и освобождения места для трамплинов в исполняемой куче. Эти функции реализованы в libgcc и будут доступны только на определенных целях: x86_64 Darwin, x86_64 и aarch64 Linux. ОБРАТИТЕ ВНИМАНИЕ: трамплины кучи не гарантируется, что будут корректно освобождены, если вы setjmp, создаёте экземпляры вложенных функций и затем longjmp возвращаетесь в состояние до выделения этих вложенных функций.

-fvisibility=[default|internal|hidden|protected]

Установите видимость символов по умолчанию в ELF-образе до указанного параметра — все символы помечаются этим, если не переопределены в коде. Использование этой функции может значительно улучшить время линковки и загрузки общих библиотек, создать более оптимизированный код, обеспечить почти идеальный экспорт API и предотвратить конфликты символов. Сильно рекомендуется использовать его во всех распространяемых вами общих объектах.

Несмотря на номенклатуру, «default» всегда означает public; т.е. доступно для связи извне общего объекта. «protected» и «internal» практически бесполезны в реальном использовании, поэтому единственным другим часто используемым параметром является «hidden». По умолчанию, если -fvisibility не указан, это «default», т.е. сделать каждый символ public.

Хорошее объяснение преимуществ обеспечения правильной видимости ELF-символов дано в «Как писать общие библиотеки» Ульрихом Дреппером (который можно найти по адресу https://www.akkadia.org/drepper/) — однако, более совершенное решение, реализованное с помощью этого параметра, заключается в том, чтобы сделать по умолчанию hidden и пометить вещи public. Это стандарт для DLL на Windows, и с -fvisibility=hidden и __attribute__ ((visibility("default"))) вместо __declspec(dllexport) вы получите практически идентичную семантику с идентичным синтаксисом. Это большое преимущество для тех, кто работает с кроссплатформенными проектами.

Для тех, кто добавляет поддержку видимости в существующий код, вам может пригодиться #pragma GCC visibility. Это работает так, что вы заключаете объявления, для которых хотите установить видимость, в (например) #pragma GCC visibility push(hidden) и #pragma GCC visibility pop. Помните, что видимость символов следует рассматривать как часть контракта интерфейса API, и, следовательно, весь новый код всегда должен указывать видимость, если она не является по умолчанию; т.е. объявления, предназначенные только для использования внутри локального DSO, всегда должны быть явно помечены как hidden, чтобы избежать накладных расходов на PLT indirection — это также делает код более читабельным и самодокументирующим. Обратите внимание, что из-за требований спецификации 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.

Обзор этих техник, их преимуществ и способов их использования можно найти по адресу https://gcc.gnu.org/wiki/Visibility.

-fstrict-volatile-bitfields

Этот параметр следует использовать, если доступ к переменным volatile bit-fields (или другим полям структуры, хотя компилятор обычно соблюдает эти типы), должен использовать один доступ шириной типа поля, выровненный по естественному выравниванию, если это возможно. Например, цели с отображенными в памяти периферийными регистрами могут потребовать, чтобы все такие обращения имели ширину 16 бит; с этим флагом вы можете объявить все периферийные bit-fields как unsigned short (предполагая, что short имеет 16 бит на этих целях), чтобы заставить GCC использовать 16-битные обращения вместо, возможно, более эффективного 32-битного обращения.

Если этот параметр отключен, компилятор использует наиболее эффективный инструкцию. В предыдущем примере это может быть 32-битная команда загрузки, даже если она обращается к байтам, не содержащим никакой части bit-field, или к периферийным регистрам, не связанным с обновляемым.

В некоторых случаях, например, когда атрибут packed применен к полю структуры, доступ к полю может быть невозможен с помощью одного чтения или записи, корректно выровненного для целевой машины. В этом случае GCC отступает и генерирует несколько обращений вместо кода, который может вызвать сбой или обрезать результат во время выполнения.

Примечание: из-за ограничений модели памяти C/C++11 записи не разрешены для изменения не bit-field членов. Поэтому рекомендуется определить все биты типа поля как члены bit-field.

Значение этого параметра по умолчанию определяется интерфейсом приложения для целевого процессора.

-fsync-libcalls

Этот параметр управляет тем, может ли какая-либо внестрочная реализация функций семейства __sync быть использована для реализации функций семейства __atomic C++11.

Значение этого параметра по умолчанию включено, поэтому единственная полезная форма параметра — -fno-sync-libcalls. Этот параметр используется в реализации библиотеки времени выполнения libatomic.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Code-Gen-Options.html

Spec-Zone.ru

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