Spec-Zone.ru › GCC 13

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

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

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

-fstack-reuse=reuse-level

Этот параметр управляет повторным использованием стековой памяти для локальных/автоматических переменных, объявленных пользователем, и временных переменных, сгенерированных компилятором. reuse_level может принимать значения ‘all’, ‘named_vars’ или ‘none’. ‘all’ включает повторное использование стековой памяти для всех локальных переменных и временных переменных, ‘named_vars’ включает повторное использование только для локальных переменных пользователя с именами, а ‘none’ полностью отключает повторное использование стековой памяти. Значение по умолчанию — ‘all’. Параметр необходим, когда программа расширяет срок существования локальной переменной области видимости или временной переменной, сгенерированной компилятором, за пределы точки, определённой языком. Когда срок существования переменной заканчивается, и если переменная хранится в памяти, оптимизирующий компилятор свободен повторно использовать её стековую память для других временных переменных или локальных переменных области видимости, диапазон жизни которых не пересекается с ней. Legacy-код, расширяющий срок жизни локальных переменных, вероятно, сломается при оптимизации повторного использования стека.

Например,

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++. Когда срок существования временной переменной заканчивается, и если временная переменная хранится в памяти, оптимизирующий компилятор свободен повторно использовать её стековую память для других временных переменных или локальных переменных области видимости, диапазон жизни которых не пересекается с ней. Однако некоторые legacy-коды полагаются на поведение более старых компиляторов, в которых стековая память временных переменных не повторно используется, агрессивное повторное использование стека может привести к ошибкам во время выполнения. Этот параметр используется для управления оптимизацией повторного использования стековой памяти временных переменных.

-ftrapv

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

-fwrapv

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

-fwrapv-pointer

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

-fstrict-overflow

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

-fexceptions

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

-fnon-call-exceptions

Генерирует код, который позволяет инструкциям отлавливания выбрасывать исключения. Обратите внимание, что это требует платформенной поддержки времени выполнения, которая не существует повсюду. Более того, он позволяет выбрасывать исключения только инструкциям отлавливания, то есть обращениям к памяти или инструкциям с плавающей точкой. Он не позволяет выбрасывать исключения из произвольных обработчиков сигналов, таких как 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 этот параметр управляет размещением глобальных переменных, определённых без инициализатора, известных в стандарте C как «пробные определения». Пробные определения отличаются от объявлений переменной с ключевым словом extern, которые не выделяют памяти.

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

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

-fno-ident

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

-finhibit-size-directive
END_OF_DOCUMENT_MARKER

Не выводить директиву .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 в настоящее время не имеют эффекта, и трамплины всегда генерируются на платформах, которые нуждаются в них для вложенных функций.

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

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

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

Хорошее объяснение преимуществ обеспечения правильной видимости ELF-символов содержится в «How To Write Shared Libraries» Ульриха Дреппера (которое можно найти по адресу 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, всегда должны быть явно помечены как скрытые, чтобы избежать накладных расходов на косвенное обращение через 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.

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

-fstrict-volatile-bitfields

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

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

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

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

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

-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-13.3.0/gcc/Code-Gen-Options.html

Spec-Zone.ru

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