Spec-Zone.ru › GCC 15

3.5 Параметры управления диалектом C++

В этом разделе описаны параметры командной строки, имеющие смысл только для программ на C++. Также можно использовать большинство параметров компилятора GNU независимо от языка программы. Например, файл firstClass.C можно скомпилировать так:

g++ -g -fstrict-enums -O -c firstClass.C

В этом примере только -fstrict-enums — параметр, предназначенный только для программ на C++; остальные параметры можно использовать с любым языком, поддерживаемым GCC.

Некоторые параметры компиляции программ на C, например -std, также применимы к программам на C++. См. Параметры управления диалектом C.

Ниже приведён список параметров, предназначенных только для компиляции программ на C++:

-fabi-version=n

Использовать версию n ABI C++. По умолчанию используется версия 0.

Версия 0 соответствует спецификации ABI C++ наиболее близко. Поэтому ABI, получаемый при использовании версии 0, меняется в разных версиях G++ по мере исправления ошибок ABI.

Версия 1 — это версия ABI C++, впервые появившаяся в G++ 3.2.

Версия 2 — это версия ABI C++, впервые появившаяся в G++ 3.4 и использовавшаяся по умолчанию до G++ 4.9.

Версия 3 исправляет ошибку в манглинге адреса константы, используемого в качестве аргумента шаблона.

Версия 4, впервые появившаяся в G++ 4.5, реализует стандартный манглинг векторных типов.

Версия 5, впервые появившаяся в G++ 4.6, исправляет манглинг атрибутов const/volatile для типов указателей на функции, decltype обычного объявления и использование параметра функции в объявлении другого параметра.

Версия 6, впервые появившаяся в G++ 4.7, исправляет поведение при продвижении ограниченных перечислений C++11 и манглинг пакетов аргументов шаблонов, const/static_cast, префиксных ++ и –, а также функции в области видимости класса, используемой в качестве аргумента шаблона.

Версия 7, впервые появившаяся в G++ 4.8, рассматривает nullptr_t как встроенный тип и исправляет манглинг лямбда-выражений в области видимости аргумента по умолчанию.

Версия 8, впервые появившаяся в G++ 4.9, исправляет поведение подстановки типов функций с квалификаторами function-cv.

Версия 9, впервые появившаяся в G++ 5.2, исправляет выравнивание nullptr_t.

Версия 10, впервые появившаяся в G++ 6.1, добавляет манглинг атрибутов, влияющих на идентичность типа, например атрибутов соглашения о вызовах ia32 (например, ‘stdcall’).

Версия 11, впервые появившаяся в G++ 7, исправляет манглинг выражений sizeof... и имён операторов. Для нескольких сущностей с одинаковым именем внутри функции, объявленных в разных областях видимости, манглинг теперь меняется начиная с двенадцатого вхождения. Она также подразумевает -fnew-inheriting-ctors.

Версия 12, впервые появившаяся в G++ 8, исправляет соглашения о вызовах для пустых классов на целевой платформе x86_64 и для классов, у которых есть только удалённые конструкторы копирования/перемещения. Она случайно меняет соглашение о вызовах для классов с удалённым конструктором копирования и тривиальным конструктором перемещения.

Версия 13, впервые появившаяся в G++ 8.2, исправляет случайное изменение в версии 12.

Версия 14, впервые появившаяся в G++ 10, исправляет манглинг выражения nullptr.

Версия 15, впервые появившаяся в G++ 10.3, исправляет регрессию ABI G++ 10, связанную с тегами ABI.

Версия 16, впервые появившаяся в G++ 11, изменяет манглинг __alignof__ так, чтобы он отличался от манглинга alignof, а также зависимых имён операторов.

Версия 17, впервые появившаяся в G++ 12, исправляет компоновку классов, наследующих агрегатные классы с инициализаторами нестатических членов по умолчанию в C++14 и более поздних версиях.

Версия 18, впервые появившаяся в G++ 13, исправляет манглинг лямбда-выражений с дополнительным контекстом.

Версия 19, впервые появившаяся в G++ 14, исправляет манглинг структурированных привязок, добавляя теги ABI.

Версия 20, впервые появившаяся в G++ 15, исправляет манглинг лямбда-выражений в инициализаторах статических членов данных.

См. также -Wabi.

-fabi-compat-version=n

На целевых платформах, поддерживающих сильные псевдонимы, G++ обходит изменения манглинга, создавая псевдоним с правильным манглированным именем при определении символа с неправильным манглированным именем. Этот параметр задаёт версию ABI, используемую для псевдонима.

При -fabi-version=0 (значение по умолчанию) по умолчанию используется версия 13 (совместимость с GCC 8.2). Если явно выбрана другая версия ABI, по умолчанию используется версия 0. Для совместимости с версиями GCC от 3.2 до 4.9 используйте -fabi-compat-version=2.

Если этот параметр не указан, но задан -Wabi=n, для псевдонимов совместимости используется указанная версия. Если этот параметр указан вместе с -Wabi (без версии), версия из этого параметра используется для предупреждения.

-fno-access-control

Отключить все проверки доступа. Этот параметр главным образом полезен для обхода ошибок в коде управления доступом.

-faligned-new

Включить поддержку C++17 new типов, которым требуется выравнивание большее, чем обеспечивает void* ::operator new(std::size_t). Числовой аргумент, например -faligned-new=32, позволяет указать выравнивание (в байтах), обеспечиваемое этой функцией, однако лишь немногим пользователям потребуется переопределять значение по умолчанию — alignof(std::max_align_t).

Этот флаг включён по умолчанию для -std=c++17.

-fno-assume-sane-operators-new

Стандарт C++ разрешает заменять глобальные операторы new, new[], delete и delete[], хотя многие программы на C++ этого не делают и используют предоставленные реализацией версии. Кроме того, стандарт C++ разрешает опускать эти вызовы, если они выполняются из выражений new или delete (и, как следствие, то же предполагается при использовании функций __builtin_operator_new или __builtin_operator_delete). Этот параметр позволяет управлять некоторыми оптимизациями вызовов этих операторов. При параметре -fassume-sane-operators-new-delete GCC может предполагать, что вызовы заменяемых глобальных операторов из выражений new или delete либо из вызовов __builtin_operator_new или __builtin_operator_delete не читают и не изменяют глобальные переменные или переменные, адрес которых может быть передан операторам (глобальное состояние; за исключением errno для операторов new и new[]). Это позволяет выполнять большинство оптимизаций через такие вызовы и соответствует поведению операторов, предоставленных реализацией, если только в коде не наблюдаются детали реализации malloc или не используются перехватчики malloc. Однако это предположение может быть неверным, если программа заменяет эти операторы. Такое поведение включено по умолчанию. При параметре -fno-assume-sane-operators-new-delete GCC должен предполагать, что все эти вызовы (из выражений new или delete либо прямые) могут читать и записывать глобальное состояние, если не доказано обратное (например, когда GCC компилирует их реализацию). Используйте этот параметр, если эти операторы заменены или могут быть заменены и код должен учитывать такое поведение.

-fchar8_t
-fno-char8_t

Включить поддержку char8_t в редакции стандарта C++20. Это включает добавление нового фундаментального типа char8_t, изменение типов строковых и символьных литералов UTF-8, новые сигнатуры литералов, определяемых пользователем, соответствующие обновления стандартной библиотеки и новые макросы проверки поддержки возможностей __cpp_char8_t и __cpp_lib_char8_t.

Этот параметр позволяет перегружать функции для обычных строк и строк UTF-8:

int f(const char *);    // #1
int f(const char8_t *); // #2
int v1 = f("text");     // Calls #1
int v2 = f(u8"text");   // Calls #2

и вводит новые сигнатуры литералов, определяемых пользователем:

int operator""_udl1(char8_t);
int v3 = u8'x'_udl1;
int operator""_udl2(const char8_t*, std::size_t);
int v4 = u8"text"_udl2;
template<typename T, T...> int operator""_udl3();
int v5 = u8"text"_udl3;

Изменение типов строковых и символьных литералов UTF-8 приводит к несовместимости со стандартом ISO C++11 и более поздними стандартами. Например, следующий код корректен согласно ISO C++11, но некорректен при указании -fchar8_t.

const char *cp = u8"xx";// error: invalid conversion from
                        //        `const char8_t*' to `const char*'
int f(const char*);
auto v = f(u8"xx");     // error: invalid conversion from
                        //        `const char8_t*' to `const char*'
std::string s{u8"xx"};  // error: no matching function for call to
                        //        `std::basic_string<char>::basic_string()'
using namespace std::literals;
s = u8"xx"s;            // error: conversion from
                        //        `basic_string<char8_t>' to non-scalar
                        //        type `basic_string<char>' requested
-fcheck-new

Проверять, что указатель, возвращённый operator new, не равен null, прежде чем пытаться изменить выделенную память. Обычно эта проверка не нужна, поскольку стандарт C++ устанавливает, что operator new возвращает 0 только в том случае, если объявлена как throw(); в этом случае компилятор всегда проверяет возвращаемое значение и без этого параметра. Во всех остальных случаях, когда operator new имеет непустую спецификацию исключений, об исчерпании памяти сигнализируется выбрасыванием std::bad_alloc. См. также ‘new (nothrow)’.

-fconcepts

Включить поддержку концептов C++ для ограничения аргументов шаблонов. В -std=c++20 и более поздних версиях концепты входят в стандарт языка, поэтому по умолчанию для -fconcepts установлено значение on.

Некоторые конструкции, разрешённые более ранним техническим описанием расширений C++ для концептов, ISO 19217 (2015), но не вошедшие в стандарт, можно было дополнительно включить с помощью -fconcepts-ts. Параметр -fconcepts-ts объявлен устаревшим в GCC 14 и удалён в GCC 15; предполагается, что пользователи преобразуют свой код на концепты C++20.

-fconstexpr-depth=n

Задать максимальную глубину вложенных вычислений функций constexpr C++11 равной n. Ограничение необходимо для обнаружения бесконечной рекурсии при вычислении константных выражений. Минимальное значение, установленное стандартом, — 512.

-fconstexpr-cache-depth=n

Задать максимальный уровень глубины вложенных вычислений функций constexpr C++11, результаты которых будут кэшироваться, равным n. Это эвристический параметр, представляющий компромисс между скоростью компиляции (когда кэш позволяет избежать повторных вычислений) и потреблением памяти (когда кэш сильно разрастается из-за глубоко рекурсивных вычислений). Значение по умолчанию — 8. Вряд ли многим пользователям потребуется его менять, но если ваш код активно выполняет вычисления constexpr, можно поэкспериментировать и подобрать оптимальное значение.

-fconstexpr-fp-except

Приложение F стандарта C указывает, что исключения IEC559 с плавающей точкой, возникающие во время компиляции, не должны останавливать компиляцию. Компиляторы C++ исторически не следовали этой рекомендации и считали деление с плавающей точкой на ноль неконстантным, хотя оно имеет чётко определённое значение. Этот флаг указывает компилятору отдавать приоритет приложению F перед другими правилами, согласно которым определённая операция является неопределённой.

constexpr float inf = 1./0.; // OK with -fconstexpr-fp-except
-fconstexpr-loop-limit=n

Задать максимальное число итераций цикла в функциях constexpr C++14 равным n. Ограничение необходимо для обнаружения бесконечных циклов при вычислении константных выражений. Значение по умолчанию — 262144 (1<<18).

-fconstexpr-ops-limit=n

Задать максимальное число операций за одно вычисление constexpr. Даже если число итераций одного цикла ограничено указанным выше значением, несколько вложенных циклов могут выполнять много итераций каждый, оставаясь в пределах этого значения; кроме того, в теле цикла или даже вне цикла может потребоваться вычислить слишком много выражений. В результате вычисление constexpr может занять слишком много времени. Значение по умолчанию — 33554432 (1<<25).

-fcontracts

Включить экспериментальную поддержку контрактов C++, которые ненадолго появились, а затем были удалены из рабочего проекта стандарта C++20 (N4820). Реализация также включает предлагаемые улучшения из документов P1290, P1332 и P1429. Эта функциональность предназначена главным образом для тех, кто хочет экспериментировать с целью доработки возможности и подготовки её к включению в будущий стандарт C++.

При нарушении проверяемого контракта вызывается обработчик нарушения. Пользователи могут заменить обработчик нарушения, определив

void
handle_contract_violation (const std::experimental::contract_violation&);

Существуют разные наборы дополнительных флагов, которые можно использовать совместно, чтобы указать, какие контракты и каким образом проверять: контракты N4820, P1332 или P1429; эти наборы нельзя использовать вместе.

-fcontract-mode=[on|off]

Управлять тем, имеют ли контракты вообще какую-либо семантику. По умолчанию включено.

-fcontract-assumption-mode=[on|off]

[N4820] Управлять тем, должна ли семантика assume применяться к контрактам с уровнем ‘axiom’. По умолчанию включено.

-fcontract-build-level=[off|default|audit]

[N4820] Указать, для какого уровня контрактов генерировать проверки. По умолчанию используется ‘default’.

-fcontract-continuation-mode=[on|off]

[N4820] Управлять тем, разрешено ли программе продолжать выполнение после нарушения контракта. Иными словами, имеют ли проверяемые контракты семантику ‘maybe’, описанную ниже, вместо семантики ‘never’. По умолчанию отключено.

-fcontract-role=<name>:<default>,<audit>,<axiom>

[P1332] Задать конкретную семантику для каждого уровня контракта определённой роли контракта.

-fcontract-semantic=[default|audit|axiom]:<semantic>

[P1429] Задать конкретную семантику для определённого уровня контракта.

-fcontract-strict-declarations=[on|off]

Управлять запретом на добавление контрактов к функции после её первого объявления. По умолчанию отключено.

Возможные конкретные варианты семантики, задаваемые с помощью ‘-fcontract-role’ или ‘-fcontract-semantic’:

ignore

Этот контракт не имеет эффекта.

assume

Этот контракт обрабатывается как [[assume]] C++23.

check_never_continue
never
abort

Этот контракт проверяется. При его нарушении вызывается обработчик нарушения. Если обработчик возвращает управление, вызывается std::terminate.

check_maybe_continue
maybe

Этот контракт проверяется. При его нарушении вызывается обработчик нарушения. Если обработчик возвращает управление, выполнение продолжается обычным образом.

-fcoroutines

Включить поддержку расширения сопрограмм C++ (экспериментальную).

-fdiagnostics-all-candidates

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

-fno-elide-constructors

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

В C++17 компилятор обязан опускать создание таких временных объектов, но этот параметр по-прежнему влияет на тривиальные функции-члены.

-fno-enforce-eh-specs

Не генерировать код для проверки нарушений спецификаций исключений во время выполнения. Этот параметр нарушает стандарт C++, но может быть полезен для уменьшения размера кода в производственных сборках, подобно определению NDEBUG. Это не даёт пользовательскому коду разрешения выбрасывать исключения в нарушение спецификаций исключений; компилятор по-прежнему выполняет оптимизацию, исходя из этих спецификаций, поэтому выбрасывание неожиданного исключения приводит к неопределённому поведению во время выполнения.

-fextern-tls-init
-fno-extern-tls-init

Стандарты C++11 и OpenMP разрешают переменным thread_local и threadprivate динамическую (во время выполнения) инициализацию. Для поддержки этого любое использование такой переменной проходит через функцию-обёртку, выполняющую необходимую инициализацию. Если использование и определение переменной находятся в одной единице трансляции, эти накладные расходы можно устранить оптимизацией; если же использование находится в другой единице трансляции, накладные расходы значительны, даже когда переменная фактически не нуждается в динамической инициализации. Если программист может быть уверен, что использование переменной в единице трансляции, отличной от содержащей её определение, не должно запускать динамическую инициализацию (либо потому, что переменная инициализируется статически, либо потому, что использование переменной в единице трансляции с её определением выполняется до любого использования в другой единице трансляции), эти накладные расходы можно устранить с помощью параметра -fno-extern-tls-init.

На целевых платформах, поддерживающих псевдонимы символов, по умолчанию используется -fextern-tls-init. На целевых платформах, не поддерживающих псевдонимы символов, по умолчанию используется -fno-extern-tls-init.

-ffold-simple-inlines
-fno-fold-simple-inlines

Разрешить интерфейсной части C++ сворачивать вызовы std::move, std::forward, std::addressof и std::as_const. В отличие от встраивания, при этом для таких вызовов не генерируется отладочная информация. Поскольку эти функции редко представляют интерес при отладке, этот флаг включён по умолчанию, если не задан -fno-inline.

-fno-gnu-keywords

Не распознавать typeof как ключевое слово, чтобы его можно было использовать в коде как идентификатор. Вместо него можно использовать ключевое слово __typeof__. Этот параметр подразумевается строгими диалектами ISO C++: -ansi, -std=c++98, -std=c++11 и т. д.

-fno-immediate-escalation

Отключить эскалацию immediate-функций, при которой определённые функции могут быть повышены до consteval, как указано в P2564R3. Например:

consteval int id(int i) { return i; }

constexpr int f(auto t)
{
  return t + id(t); // id causes f<int> to be promoted to consteval
}

void g(int i)
{
  f (3);
}

компилируется в C++20: f — функция с эскалацией immediate (из-за auto она является шаблоном функции и объявлена как constexpr), а id(t) — выражение с эскалацией immediate, поэтому f повышается до consteval. Следовательно, вызов id(t) происходит в immediate-контексте и не обязан давать константу (именно этот механизм позволяет составлять consteval-функции). Однако при -fno-immediate-escalation f не повышается до consteval, и поскольку вызов функции consteval id(t) не является константным выражением, компилятор отклоняет код.

Этот параметр включён по умолчанию; он действует только в режиме C++20 или более позднем.

-fimplicit-constexpr

Неявно объявлять встроенные функции constexpr, если они соответствуют требованиям к функции constexpr. Этот параметр можно использовать в режиме C++14 или более позднем. Это может привести к переходу от динамической инициализации к статической и к другим оптимизациям.

-fno-implicit-templates

Никогда не генерировать код для невстроенных шаблонов, неявно инстанцированных (то есть в результате использования); генерировать код только для явных инстанцирований. Если вы используете этот параметр, необходимо правильно структурировать код и включить все необходимые явные инстанцирования, чтобы при компоновке не возникали неопределённые символы. Дополнительные сведения см. в разделе Где же шаблон?.

-fno-implicit-inline-templates

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

-fno-implement-inlines

Для экономии места не генерировать копии встроенных функций вне строки, управляемые #pragma implementation. Это приводит к ошибкам компоновки, если такие функции не встроены во всех местах вызова.

-fmodules
-fno-modules

Включить поддержку модулей C++20 (см. раздел Модули C++). Обычно параметр -fno-modules не нужен, поскольку это значение используется по умолчанию. Хотя модули относятся к возможностям C++20, выбор этой версии стандарта в настоящее время не включает их автоматически.

-fmodule-header
-fmodule-header=user
-fmodule-header=system

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

-fmodule-implicit-inline

Функции-члены, определённые внутри определения класса, не становятся неявно встроенными в модульном коде. Это отличается от традиционного поведения C++ и имеет веские причины. Однако это может затруднить перенос кода. Этот параметр делает такие определения функций неявно встроенными. При этом возникает несовместимость ABI, поэтому параметр необходимо использовать везде или нигде. (Такие определения вне именованного модуля в любом случае остаются неявно встроенными.)

-fno-module-lazy

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

-fmodule-mapper=[hostname]:port[?ident]
-fmodule-mapper=|program[?ident] args...
-fmodule-mapper==socket[?ident]
-fmodule-mapper=<>[inout][?ident]
-fmodule-mapper=<in>out[?ident]
-fmodule-mapper=file[?ident]

Средство для получения соответствий между именами модулей и именами файлов. Если оно не задано, используется переменная среды CXX_MODULE_MAPPER, а если она не установлена, предоставляется встроенное значение по умолчанию.

-fmodule-only

Выводить только скомпилированный интерфейс модуля, не создавая объектный файл.

-fms-extensions

Отключить предупреждения Wpedantic о конструкциях, используемых в MFC, например о неявном int и получении указателя на функцию-член с помощью нестандартного синтаксиса.

-fnew-inheriting-ctors

Включить изменение семантики наследования конструкторов C++11, предложенное в P0136. Это изменение входит в C++17, но также считается отчётом об ошибке для C++11 и C++14. Этот флаг включён по умолчанию, если не указано -fabi-version=10 или более раннее значение.

-fnew-ttp-matching

Включить решение P0522 по основному вопросу 150 о параметрах-шаблонах шаблона и аргументах по умолчанию: оно разрешает передавать шаблон с аргументами шаблона по умолчанию в качестве аргумента параметру-шаблону шаблона с меньшим числом параметров шаблона. Этот флаг включён по умолчанию для -std=c++17.

-fno-nonansi-builtins

Отключить встроенные объявления функций, обязательных по ANSI/ISO C. К ним относятся ffs, alloca, _exit, index, bzero, conjf и другие связанные функции.

-fnothrow-opt

Обрабатывать спецификацию исключений throw() как спецификацию noexcept, чтобы уменьшить или устранить накладные расходы на размер кода по сравнению с функцией без спецификации исключений. Если функция содержит локальные переменные типов с нетривиальными деструкторами, спецификация исключений фактически уменьшает размер функции, поскольку очистки EH для этих переменных можно оптимизировать. Семантический эффект заключается в том, что исключение, выброшенное из функции с такой спецификацией исключений, приводит к вызову terminate вместо unexpected.

-fno-operator-names

Не считать ключевые слова — имена операторов and, bitand, bitor, compl, not, or и xor — синонимами ключевых слов.

-fno-optional-diags

Отключить диагностику, которую стандарт не обязывает выдавать компилятор. В настоящее время единственное такое сообщение, выдаваемое G++, относится к имени с несколькими значениями внутри класса.

-fno-pretty-templates

Если сообщение об ошибке относится к специализации шаблона функции, компилятор обычно выводит сигнатуру шаблона, за которой следуют аргументы шаблона и любые псевдонимы типов или имена типов в сигнатуре (например, void f(T) [with T = int], а не void f(int)), чтобы было понятно, о каком шаблоне идёт речь. Если сообщение об ошибке относится к специализации шаблона класса, компилятор опускает аргументы шаблона, совпадающие с аргументами шаблона по умолчанию для этого шаблона. Если какое-либо из этих правил затрудняет понимание сообщения об ошибке, а не упрощает его, можно отключить их с помощью -fno-pretty-templates.

-frange-for-ext-temps

Включить продление времени жизни временных объектов в циклах for на основе диапазона C++. В -std=c++23 и более поздних версиях это входит в стандарт языка, поэтому время жизни временных объектов по умолчанию продлевается до конца цикла. Этот параметр позволяет включить такое поведение и в более ранних версиях стандарта.

-fno-rtti

Отключить генерацию информации обо всех классах с виртуальными функциями, используемой средствами идентификации типов во время выполнения C++ (dynamic_cast и typeid). Если вы не используете эти возможности языка, этот флаг позволяет сэкономить место. Обратите внимание, что обработка исключений использует ту же информацию, но G++ генерирует её по мере необходимости. Оператор dynamic_cast по-прежнему можно использовать для приведений, которым не требуется информация о типе во время выполнения, то есть для приведений к void * или к однозначным базовым классам.

Совместное использование кода, скомпилированного с -frtti и -fno-rtti, может привести к сбоям. Например, программа может не скомпоноваться, если класс, скомпилированный с -fno-rtti, используется как базовый для класса, скомпилированного с -frtti.

-fsized-deallocation

Включить встроенные глобальные объявления

void operator delete (void *, std::size_t) noexcept;
void operator delete[] (void *, std::size_t) noexcept;

введённые в C++14. Это полезно для определяемых пользователем функций замены освобождения памяти, которые, например, используют размер объекта для ускорения освобождения. По умолчанию включено для -std=c++14 и более поздних версий. Флаг -Wsized-deallocation предупреждает о местах, где может потребоваться добавить определение.

-fstrict-enums

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

-fstrong-eval-order
-fstrong-eval-order=kind

Вычислять доступ к членам, индексирование массива и выражения сдвига слева направо, а присваивание — справа налево, как принято для C++17. Параметр -fstrong-eval-order эквивалентен -fstrong-eval-order=all и включён по умолчанию для -std=c++17 и более поздних версий.

-fstrong-eval-order=some включает только упорядочение доступа к членам и вычисления выражений сдвига и используется по умолчанию для диалектов C++ до C++17.

-fstrong-eval-order=none эквивалентен -fno-strong-eval-order.

-ftemplate-backtrace-limit=n

Задать максимальное число примечаний об инстанцировании шаблона для одного предупреждения или ошибки равным n. Значение по умолчанию — 10.

-ftemplate-depth=n

Задать максимальную глубину инстанцирования шаблонов классов равной n. Ограничение глубины инстанцирования шаблонов необходимо для обнаружения бесконечной рекурсии при инстанцировании шаблонов классов. Программы, соответствующие ANSI/ISO C++, не должны рассчитывать на максимальную глубину больше 17 (в C++11 она увеличена до 1024). Значение по умолчанию — 900, поскольку в некоторых ситуациях компилятор может исчерпать стек до достижения 1024.

-fno-threadsafe-statics

Не генерировать дополнительный код для использования процедур, определённых ABI C++ для потокобезопасной инициализации локальных статических переменных. Этот параметр позволяет немного уменьшить размер кода, которому не требуется потокобезопасность.

-fuse-cxa-atexit

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

-fno-use-cxa-get-exception-ptr

Не использовать процедуру времени выполнения __cxa_get_exception_ptr. Из-за этого std::uncaught_exception работает некорректно, но это необходимо, если процедура времени выполнения недоступна.

-fvisibility-inlines-hidden

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

В результате GCC может фактически помечать встроенные методы с помощью __attribute__ ((visibility ("hidden"))), чтобы они не появлялись в таблице экспорта DSO и при использовании внутри DSO не требовали косвенного перехода через PLT. Включение этого параметра может значительно сократить время загрузки и компоновки DSO, поскольку оно резко уменьшает размер динамической таблицы экспорта, если библиотека активно использует шаблоны.

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

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

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

-fvisibility-ms-compat

Этот флаг пытается использовать настройки видимости, чтобы сделать модель связывания C++ в GCC совместимой с моделью Microsoft Visual Studio.

Флаг вносит следующие изменения в модель связывания GCC:

  1. Он устанавливает видимость по умолчанию в hidden, как и -fvisibility=hidden.
  2. Типы, но не их члены, по умолчанию не являются скрытыми.
  3. Правило одного определения ослабляется для типов без явных спецификаций видимости, определенных более чем в одном разделяемом объекте: такие объявления допускаются, если они допускались бы при отключенном параметре.

В новом коде лучше использовать -fvisibility=hidden и экспортировать классы, которые должны быть видимы извне. К сожалению, код может полагаться — возможно, случайно — на поведение Visual Studio.

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

-fno-weak

Не использовать поддержку слабых символов, даже если она предоставляется компоновщиком. По умолчанию G++ использует слабые символы, если они доступны. Этот параметр существует только для тестирования и не должен использоваться конечными пользователями: он приводит к ухудшению кода и не дает никаких преимуществ. В будущем выпуске G++ этот параметр может быть удален.

-fext-numeric-literals (C++ and Objective-C++ only)

Принимать суффиксы мнимых, фиксированных или определяемых машиной числовых литералов как расширения GNU. Если этот параметр отключен, такие суффиксы считаются суффиксами числовых литералов, определяемыми пользователем в C++11. По умолчанию параметр включен для всех диалектов до C++11 и всех диалектов GNU: -std=c++98, -std=gnu++98, -std=gnu++11, -std=gnu++14. Для ISO C++11 и более поздних версий он по умолчанию отключен (-std=c++11, ...).

-nostdinc++

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

-flang-info-include-translate
-flang-info-include-translate-not
-flang-info-include-translate=header

Сообщать о событиях преобразования директив включения. Первый вариант сообщает о выполненных преобразованиях директив включения, второй — об отклоненных. Вариант с header сообщает о преобразованиях директив включения, относящихся к указанному заголовочному файлу. Если header имеет вид "user" или <system>, он будет сопоставлен с конкретным пользовательским или системным заголовочным файлом с использованием пути поиска включаемых файлов.

-flang-info-module-cmi
-flang-info-module-cmi=module

Сообщать имена путей интерфейсов скомпилированных модулей. Первый вариант сообщает обо всех прочитанных именах путей CMI. Вариант с module не будет читать CMI указанного модуля. module может быть именованным модулем или единицей заголовка (последняя обозначается либо именем пути, содержащим разделители каталогов, либо записью в <> или "").

-stdlib=libstdc++,libc++

Если G++ настроен на поддержку этого параметра, он позволяет указать альтернативные библиотеки среды выполнения C++. Доступны два варианта: libstdc++ (вариант по умолчанию, собственная среда выполнения C++ для G++) и libc++ — среда выполнения C++, установленная в некоторых операционных системах (например, в Darwin, начиная с версии Darwin11). Этот параметр переключает G++ на использование заголовочных файлов указанной библиотеки и на генерацию -lstdc++ или -lc++ соответственно, когда для компоновки требуется среда выполнения C++.

Кроме того, следующие параметры предупреждений имеют смысл только для программ на C++:

-Wabi-tag (C++ and Objective-C++ only)

Предупреждать, если тип с тегом ABI используется в контексте, в котором этот тег ABI отсутствует. Дополнительные сведения о тегах ABI см. в разделе Атрибуты переменных, функций и типов, специфичные для C++.

-Wcomma-subscript (C++ and Objective-C++ only)

Предупреждать об использовании оператора-запятой в выражении индексации. Такое использование устарело в C++20 и будет удалено в C++23. Однако оператор-запятая, заключённый в ( ), не считается устаревшим. Пример:

void f(int *a, int b, int c) {
    a[b,c];     // deprecated in C++20, invalid in C++23
    a[(b,c)];   // OK
}

В C++23 в выражении индексации допустимы выражения, разделённые запятыми, если найден перегруженный оператор индексации, поддерживающий нужное количество аргументов соответствующих типов. G++ принимает ранее допустимый синтаксис в коде, который не соответствует требованиям C++23, но был допустимым, хотя и устаревшим в C++20; при этом выдаётся предупреждение, которое можно отключить с помощью -Wno-comma-subscript.

По умолчанию включено с -std=c++20, если не задано -Wno-deprecated, а начиная с -std=c++23 — независимо от -Wno-deprecated. До -std=c++20 включается явным указанием -Wdeprecated.

В режиме C++23 и более поздних режимах это предупреждение повышается до ошибки параметром -pedantic-errors.

-Wctad-maybe-unsupported (C++ and Objective-C++ only)

Предупреждать при выводе аргументов шаблона класса (CTAD) для типа, у которого явно не заданы направляющие вывода. Это предупреждение указывает на случаи, когда CTAD сработал только благодаря неявным направляющим вывода, сгенерированным компилятором, что может не соответствовать намерениям программиста. Некоторые руководства по стилю допускают CTAD только для типов, специально «выбирающих» эту возможность, то есть разработанных для поддержки CTAD. Это предупреждение можно подавить с помощью следующего шаблона:

struct allow_ctad_t; // any name works
template <typename T> struct S {
  S(T) { }
};
// Guide with incomplete parameter type will never be considered.
S(allow_ctad_t) -> S<void>;
-Wctor-dtor-privacy (C++ and Objective-C++ only)

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

-Wdangling-reference (C++ and Objective-C++ only)

Предупреждать, если ссылка привязана к временному объекту, время жизни которого завершилось. Например:

int n = 1;
const int& r = std::max(n - 1, n + 1); // r is dangling

В приведённом выше примере создаются два временных объекта — по одному для каждого аргумента, — и возвращается ссылка на один из них. Однако оба временных объекта уничтожаются в конце полного выражения, поэтому ссылка r становится висячей. Это предупреждение также обнаруживает висячие ссылки в списках инициализации членов:

const int& f(const int& i) { return i; }
struct S {
  const int &r; // r is dangling
  S() : r(f(10)) { }
};

Проверяются и функции-члены, но только их объектный аргумент:

struct S {
   const S& self () { return *this; }
};
const S& s = S().self(); // s is dangling

Некоторые функции в этом отношении безопасны, например std::use_facet: они принимают и возвращают ссылку, но не возвращают одну из своих аргументных ссылок, что может ввести предупреждение в заблуждение. Такие функции можно исключить из проверки, обернув их в #pragma:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-reference"
const T& foo (const T&) { … }
#pragma GCC diagnostic pop

#pragma можно также применить ко всему классу; в этом случае предупреждение будет отключено для всех функций-членов.

-Wdangling-reference также предупреждает о коде вида

auto p = std::minmax(1, 2);

где std::minmax возвращает std::pair<const int&, const int&>, а обе ссылки становятся висячими после завершения полного выражения, содержащего вызов std::minmax.

Предупреждение не выдаётся для классов вида std::span. Мы считаем классы следующей формы:

template<typename T>
struct Span {
  T* data_;
  std::size len_;
};

подобными std::span; то есть это невариантный класс, у которого есть указатель в качестве поля данных и тривиальный деструктор.

Предупреждение можно отключить с помощью атрибута gnu::no_dangling (см. раздел Атрибуты переменных, функций и типов, специфичные для C++).

Это предупреждение включается параметром -Wextra.

-Wdelete-non-virtual-dtor (C++ and Objective-C++ only)

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

-Wdeprecated-copy (C++ and Objective-C++ only)

Предупреждать об устаревшем неявном объявлении конструктора копирования или оператора присваивания копированием, если в классе есть пользовательский конструктор копирования или оператор присваивания копированием (начиная с C++11). Это предупреждение включается параметром -Wextra. С параметром -Wdeprecated-copy-dtor объявление также считается устаревшим, если в классе есть пользовательский деструктор.

-Wno-deprecated-enum-enum-conversion (C++ and Objective-C++ only)

Отключить предупреждение о применении обычных арифметических преобразований к операндам, один из которых имеет перечислимый тип, а другой — другой перечислимый тип. Это преобразование устарело в C++20. Например:

enum E1 { e };
enum E2 { f };
int k = f - e;

-Wdeprecated-enum-enum-conversion включён по умолчанию с -std=c++20. В диалектах до C++20 это предупреждение можно включить параметром -Wenum-conversion или -Wdeprecated.

-Wno-deprecated-enum-float-conversion (C++ and Objective-C++ only)

Отключить предупреждение о применении обычных арифметических преобразований к операндам, один из которых имеет перечислимый тип, а другой — тип с плавающей точкой. Это преобразование устарело в C++20. Например:

enum E1 { e };
enum E2 { f };
bool b = e <= 3.7;

-Wdeprecated-enum-float-conversion включён по умолчанию с -std=c++20. В диалектах до C++20 это предупреждение можно включить параметром -Wenum-conversion или -Wdeprecated.

-Wdeprecated-literal-operator (C++ and Objective-C++ only)

Предупреждать об устаревшем объявлении определяемого пользователем оператора литерала, если перед суффиксом стоит пробел. Это предупреждение включено по умолчанию в C++23 или при явном указании -Wdeprecated.

string operator "" _i18n(const char*, std::size_t); // deprecated
string operator ""_i18n(const char*, std::size_t); // preferred
-Wdeprecated-variadic-comma-omission (C++ and Objective-C++ only)

Предупреждать об устаревшем пропуске запятой перед ... для переменного числа аргументов в конце списка параметров функции. Это предупреждение включено по умолчанию в C++26 или при явном указании -Wdeprecated.

void f1(int...); // deprecated
void f1(int, ...); // preferred
template <typename ...T>
void f2(T...); // ok
template <typename ...T>
void f3(T......); // deprecated
-Wno-elaborated-enum-base

Для C++11 и более поздних версий предупреждать об использовании дополнительного базового типа перечисления (недопустимого) в спецификаторе развёрнутого типа. То есть предупреждать, если перечисление с заданным базовым типом и без списка перечислителей используется в объявлении, отличном от отдельного объявления самого перечисления. Включено по умолчанию. Это предупреждение повышается до ошибки параметром -pedantic-errors.

-Wno-init-list-lifetime (C++ and Objective-C++ only)

Не предупреждать об использовании std::initializer_list, которое может привести к появлению висячих указателей. Поскольку базовый массив для initializer_list обрабатывается как обычный временный объект C++, легко случайно сохранить указатель на массив после окончания времени его жизни. Например:

  • Если функция возвращает временный initializer_list или локальную переменную initializer_list, время жизни массива заканчивается в конце оператора return, поэтому возвращаемое значение содержит висячий указатель.
  • Если new-выражение создаёт initializer_list, массив существует только до конца заключающего его полного выражения, поэтому initializer_list в динамической памяти содержит висячий указатель.
  • Когда переменной initializer_list присваивается список инициализации в фигурных скобках, временный массив, созданный для правой части присваивания, существует только до конца полного выражения, поэтому в следующем операторе переменная initializer_list содержит висячий указатель.
    // li's initial underlying array lives as long as li
    std::initializer_list<int> li = { 1,2,3 };
    // assignment changes li to point to a temporary array
    li = { 4, 5 };
    // now the temporary is gone and li has a dangling pointer
    int i = li.begin()[0] // undefined behavior
  • Если конструктор со списком сохраняет указатель begin из аргумента initializer_list, время жизни массива не продлевается, поэтому при создании переменной класса из временного initializer_list указатель становится висячим в конце оператора объявления переменной.
-Winvalid-constexpr

Предупреждать, если функция никогда не вычисляется как константное выражение. В C++20 и более ранних версиях для каждой функции constexpr и каждого шаблона функции должен существовать хотя бы один набор аргументов функции как минимум в одной инстанциации, при котором вызов функции или конструктора может быть вычисляемым подвыражением основного константного выражения. В C++23 это ограничение снято, поэтому функция или шаблон функции могут быть помечены как constexpr, даже если ни один вызов не удовлетворяет требованиям основного константного выражения.

В C++20 и более ранних версиях это предупреждение по умолчанию включено как предупреждение о строгом соответствии стандарту. В C++23 можно включить -Winvalid-constexpr; в этом случае оно будет обычным предупреждением. Например:

void f (int& i);
constexpr void
g (int& i)
{
  // Warns by default in C++20, in C++23 only with -Winvalid-constexpr.
  f(i);
}
-Winvalid-imported-macros

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

-Wno-literal-suffix (C++ and Objective-C++ only)

Не предупреждать, если за строковым или символьным литералом следует суффикс ud, начинающийся не с символа подчёркивания. В качестве совместимого расширения GCC рассматривает такие суффиксы как отдельные лексемы препроцессора, чтобы обеспечить обратную совместимость с кодом, использующим макросы форматирования из <inttypes.h>. Например:

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdio.h>

int main() {
  int64_t i64 = 123;
  printf("My int64: %" PRId64"\n", i64);
}

В этом случае PRId64 рассматривается как отдельная лексема препроцессора.

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

Эти предупреждения включены по умолчанию.

-Wno-narrowing (C++ and Objective-C++ only)

В стандартах C++11 и более поздних версий о сужающих преобразованиях по умолчанию выдаются сообщения, как того требует стандарт. Сужающее преобразование константы приводит к ошибке, а сужающее преобразование неконстантного значения — к предупреждению, но -Wno-narrowing подавляет это сообщение. Обратите внимание, что это не меняет смысл корректного кода; сужающие преобразования по-прежнему считаются некорректными в контекстах SFINAE.

С параметром -Wnarrowing в C++98 предупреждать о сужающих преобразованиях, запрещённых в C++11, внутри «{ }», например:

int i = { 2.2 }; // error: narrowing from double to int

Этот флаг входит в -Wall и -Wc++11-compat.

-Wnoexcept (C++ and Objective-C++ only)

Предупреждать, если noexcept-выражение вычисляется как false из-за вызова функции, у которой отсутствует спецификация исключений, гарантирующая отсутствие исключений (то есть throw() или noexcept), но компилятору известно, что она никогда не выбрасывает исключение.

-Wnoexcept-type (C++ and Objective-C++ only)

Предупреждать, если возможность C++17, делающая noexcept частью типа функции, меняет декорированное имя символа по сравнению с C++14. Включается параметрами -Wabi и -Wc++17-compat.

Например:

template <class T> void f(T t) { t(); };
void g() noexcept;
void h() { f(g); }

В C++14 f вызывает f<void(*)()>, а в C++17 — f<void(*)()noexcept>.

-Wclass-memaccess (C++ and Objective-C++ only)

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

std::string str = "abc";
memset (&str, 0, sizeof str);

Параметр -Wclass-memaccess включается параметром -Wall. Явное приведение указателя на объект класса к void * или к типу, к которому можно безопасно обращаться функцией работы с необработанной памятью, подавляет предупреждение.

-Wnon-virtual-dtor (C++ and Objective-C++ only)

Предупреждать, если у класса есть виртуальные функции и доступный невиртуальный деструктор — непосредственно в самом классе или в доступном полиморфном базовом классе. В этом случае удалить экземпляр производного класса через указатель на сам класс или его базовый класс возможно, но небезопасно. Это предупреждение автоматически включается при указании -Weffc++. Следует предпочесть параметр -Wdelete-non-virtual-dtor (включённый параметром -Wall), поскольку он предупреждает о небезопасных случаях без ложных срабатываний.

-Wregister (C++ and Objective-C++ only)

Предупреждать об использовании спецификатора класса хранения register, за исключением случаев, когда он является частью расширения GNU Переменные в указанных регистрах. Использование ключевого слова register в качестве спецификатора класса хранения устарело в C++11 и было удалено в C++17. Включено по умолчанию с -std=c++17.

-Wreorder (C++ and Objective-C++ only)

Предупреждать, если порядок инициализаторов членов, указанный в коде, не соответствует порядку их выполнения. Например:

struct A {
  int i;
  int j;
  A(): j (0), i (1) { }
};

Компилятор переставляет инициализаторы членов i и j в соответствии с порядком объявления членов и выдаёт соответствующее предупреждение. Это предупреждение включается параметром -Wall.

-Wno-pessimizing-move (C++ and Objective-C++ only)

Это предупреждение выдаётся, если вызов std::move препятствует устранению копирования. Типичный случай, когда возможно устранение копирования, — возврат из функции с возвращаемым типом-классом, если возвращаемое выражение является именем автоматического объекта без квалификатора volatile, не является параметром функции и имеет тот же тип, что и возвращаемый тип функции.

struct T {
…
};
T fn()
{
  T t;
  …
  return std::move (t);
}

Однако в этом примере вызов std::move препятствует устранению копирования.

Это предупреждение включается параметром -Wall.

-Wno-redundant-move (C++ and Objective-C++ only)

Это предупреждение указывает на избыточные вызовы std::move, то есть на случаи, когда операция перемещения была бы выполнена и без вызова std::move. Это происходит потому, что в некоторых ситуациях, например при возврате локальной переменной, когда устранение копирования неприменимо, компилятор вынужден рассматривать объект как rvalue. Рассмотрим следующий пример:

struct T {
…
};
T fn(T t)
{
  …
  return std::move (t);
}

Здесь вызов std::move избыточен. Поскольку G++ реализует Core Issue 1579, можно привести ещё один пример:

struct T { // convertible to U
…
};
struct U {
…
};
U fn()
{
  T t;
  …
  return std::move (t);
}

В этом примере устранение копирования неприменимо, поскольку тип возвращаемого выражения отличается от возвращаемого типа функции, однако G++ рассматривает возвращаемое значение так, как если бы оно было представлено rvalue.

Это предупреждение включается параметром -Wextra.

-Wrange-loop-construct (C++ and Objective-C++ only)

Это предупреждение указывает на ненужное копирование в цикле for на основе диапазона в C++. Такое происходит, если объявление переменной диапазона не является ссылкой, хотя, вероятно, должно ею быть. Например:

struct S { char arr[128]; };
void fn () {
  S arr[5];
  for (const auto x : arr) { … }
}

Предупреждение не выдаётся, если копируемый тип является тривиально копируемым типом размером менее 64 байт.

Это предупреждение также выдаётся, если переменная цикла for на основе диапазона инициализируется значением другого типа, что приводит к копированию. Например:

void fn() {
  int arr[10];
  for (const double &x : arr) { … }
}

В приведённом выше примере на каждой итерации цикла создаётся и уничтожается временное значение типа double, к которому привязывается ссылка const double &.

Это предупреждение включается параметром -Wall.

-Wredundant-tags (C++ and Objective-C++ only)

Предупреждать об избыточном указании ключевого слова класса или перечисления при ссылках на классовые и перечислимые типы в контекстах, где его можно опустить без возникновения неоднозначности. Например:

struct foo;
struct foo *p;   // warn that keyword struct can be eliminated

В следующем примере предупреждение не выдаётся:

struct foo;
void foo ();   // "hides" struct foo
void bar (struct foo&);  // no warning, keyword struct is necessary
-Wno-subobject-linkage (C++ and Objective-C++ only)

Не предупреждать, если у классового типа есть базовый класс или поле, тип которого использует анонимное пространство имён или зависит от типа без связи. Если тип A зависит от типа B без связи или с внутренней связью, его определение в нескольких единицах трансляции нарушит правило одного определения (ODR), поскольку смысл B различается в каждой единице трансляции. Если A встречается только в одной единице трансляции, лучший способ отключить предупреждение — обеспечить ему внутреннюю связь, поместив его также в анонимное пространство имён. Компилятор не выдаёт это предупреждение для типов, определённых в основном файле .C, поскольку маловероятно, что у них будет несколько определений. Параметр -Wsubobject-linkage включён по умолчанию.

-Weffc++ (C++ and Objective-C++ only)

Предупреждать о нарушениях следующих рекомендаций по стилю из серии книг Скотта Мейерса Effective C++:

  • Определять конструктор копирования и оператор присваивания для классов с динамически выделяемой памятью.
  • В конструкторах предпочитать инициализацию присваиванию.
  • Пусть operator= возвращает ссылку на *this.
  • Не пытаться возвращать ссылку, если необходимо вернуть объект.
  • Различать префиксную и постфиксную формы операторов инкремента и декремента.
  • Никогда не перегружать &&, || или ,.

Этот параметр также включает -Wnon-virtual-dtor, который тоже входит в рекомендации Effective C++. Однако проверка расширена: предупреждение выдаётся и при отсутствии виртуального деструктора в доступных неполиморфных базовых классах.

При выборе этого параметра помните, что заголовочные файлы стандартной библиотеки не соответствуют всем этим рекомендациям; используйте «grep -v», чтобы отфильтровать эти предупреждения.

-Wno-exceptions (C++ and Objective-C++ only)

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

-Wstrict-null-sentinel (C++ and Objective-C++ only)

Предупреждать об использовании неприведённого NULL в качестве маркера конца. При компиляции только с GCC это допустимый маркер, поскольку NULL определён как __null. Хотя это константа нулевого указателя, а не нулевой указатель, её размер гарантированно совпадает с размером указателя. Однако такое использование несовместимо с другими компиляторами.

-Wno-non-template-friend (C++ and Objective-C++ only)

Отключить предупреждения об объявлении нешаблонных функций-друзей внутри шаблона. В очень старых версиях GCC, предшествовавших реализации стандарта ISO, объявления вида «friend int foo(int)», где имя друга является неквалифицированным идентификатором, могли интерпретироваться как конкретная специализация шаблонной функции; это предупреждение предназначено для выявления проблем совместимости и включено по умолчанию.

-Wold-style-cast (C++ and Objective-C++ only)

Предупреждать об использовании в программе на C++ приведения в стиле C к типу, отличному от void. Приведения в новом стиле (dynamic_cast, static_cast, reinterpret_cast и const_cast) менее подвержены непреднамеренным побочным эффектам, и их гораздо легче найти.

-Woverloaded-virtual (C++ and Objective-C++ only)
-Woverloaded-virtual=n

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

struct A {
  virtual void f();
};

struct B: public A {
  void f(int); // does not override
};

версия f для класса A скрыта в B, и код вида:

B* b;
b->f();

не компилируется.

Если различия в сигнатурах не являются случайными, простейшее решение — добавить в производный класс объявление using, чтобы сделать функцию базового класса видимой; например, добавить using A::f; в B.

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

struct C {
  virtual void f();
  virtual void f(int);
};

struct D: public C {
  void f(int); // does override
}

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

На уровне 1 предупреждение в этом случае не выдаётся, на уровне 2 — выдаётся. Параметр -Woverloaded-virtual без суффикса выбирает уровень 2. Уровень 1 включён в -Wall.

-Wno-pmf-conversions (C++ and Objective-C++ only)

Отключить диагностику преобразования указателя на функцию-член с привязкой в обычный указатель.

-Wsign-promo (C++ and Objective-C++ only)

Предупреждать, если при разрешении перегрузки выбирается повышение типа без знака или перечислимого типа до типа со знаком вместо преобразования в тип без знака того же размера. В предыдущих версиях G++ пытался сохранять признак отсутствия знака, но стандарт требует текущего поведения.

-Wtemplates (C++ and Objective-C++ only)

Предупреждать при обнаружении объявления первичного шаблона. Некоторые правила разработки запрещают шаблоны, и это предупреждение можно использовать для соблюдения такого правила. Предупреждение не действует внутри системного заголовочного файла, например STL, поэтому STL по-прежнему можно использовать. Шаблоны также можно инстанцировать и специализировать.

-Wmismatched-new-delete (C++ and Objective-C++ only)

Предупреждать о несоответствиях между вызовами operator new или operator delete и соответствующим вызовом функции выделения или освобождения памяти. Сюда входят вызовы C++ operator delete с указателями, возвращёнными несовпадающими формами operator new или другими функциями, выделяющими объекты, для которых operator delete не подходит в качестве функции освобождения памяти, а также вызовы других функций освобождения памяти с указателями, возвращёнными operator new, для которых эта функция освобождения памяти не подходит.

Например, выражение delete в приведённой ниже функции диагностируется, поскольку оно не соответствует форме массива выражения new, из которого был получен аргумент-указатель. Аналогично диагностируется вызов free.

void f ()
{
  int *a = new int[n];
  delete a;   // warning: mismatch in array forms of expressions

  char *p = new char[n];
  free (p);   // warning: mismatch between new and free
}

Связанный параметр -Wmismatched-dealloc диагностирует несоответствия с участием функций выделения и освобождения памяти, отличных от operator new и operator delete.

-Wmismatched-new-delete входит в -Wall.

-Wmismatched-tags (C++ and Objective-C++ only)

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

Например, объявление struct Object в списке аргументов draw вызывает предупреждение. Чтобы избежать его, удалите избыточное ключевое слово класса struct или замените его на class, чтобы оно соответствовало определению.

class Object {
public:
  virtual ~Object () = 0;
};
void draw (struct Object*);

Объявление класса с ключевым словом struct не является ошибкой, как показывает приведённый выше пример. Параметр -Wmismatched-tags предназначен для обеспечения единообразного стиля объявлений классов. В коде, который должен быть переносимым на компиляторы для Windows, это предупреждение помогает предотвратить неразрешённые ссылки, возникающие из-за различий в декорировании символов, объявленных с разными ключевыми словами класса. Параметр можно использовать отдельно или вместе с -Wredundant-tags.

-Wmultiple-inheritance (C++ and Objective-C++ only)

Предупреждать, если класс определён с несколькими непосредственными базовыми классами. Некоторые правила разработки запрещают множественное наследование, и это предупреждение можно использовать для соблюдения такого правила. Предупреждение не действует внутри системного заголовочного файла, например STL, поэтому STL по-прежнему можно использовать. Также можно определять классы, в которых множественное наследование используется косвенно.

-Wvirtual-inheritance

Предупреждать, если класс определён с непосредственным виртуальным базовым классом. Некоторые правила разработки запрещают множественное наследование, и это предупреждение можно использовать для соблюдения такого правила. Предупреждение не действует внутри системного заголовочного файла, например STL, поэтому STL по-прежнему можно использовать. Также можно определять классы, в которых виртуальное наследование используется косвенно.

-Wno-virtual-move-assign

Подавлять предупреждения о наследовании от виртуального базового класса с нетривиальным оператором перемещающего присваивания C++11. Это опасно: если до виртуального базового класса можно добраться по нескольким путям, он перемещается несколько раз, из-за чего оба объекта могут оказаться в перемещённом состоянии. Если оператор перемещающего присваивания написан так, чтобы не перемещать объект из уже перемещённого состояния, это предупреждение можно отключить.

-Wnamespaces

Предупреждать об открытии определения пространства имён. Некоторые правила разработки запрещают пространства имён, и это предупреждение можно использовать для соблюдения такого правила. Предупреждение не действует внутри системного заголовочного файла, например STL, поэтому STL по-прежнему можно использовать. Также можно использовать директивы using и квалифицированные имена.

-Wno-template-body (C++ and Objective-C++ only)

Отключить диагностику ошибок при разборе шаблона и вместо этого выдавать ошибку только при инстанцировании шаблона. Этот флаг также можно использовать для понижения таких ошибок до предупреждений с помощью Wno-error= или -fpermissive.

-Wno-template-id-cdtor (C++ and Objective-C++ only)

Отключить предупреждение об использовании simple-template-id в качестве declarator-id конструктора или деструктора; это стало недопустимым в C++20 согласно DR 2237. Например:

template<typename T> struct S {
  S<T>(); // should be S();
  ~S<T>();  // should be ~S();
};

-Wtemplate-id-cdtor включён по умолчанию с -std=c++20; он также включается параметром -Wc++20-compat.

-Wtemplate-names-tu-local

Предупреждать, если тело шаблона скрывает использование сущности, локальной для единицы трансляции. В большинстве случаев обращение к сущности, локальной для единицы трансляции (например, к объявлению с внутренней связью), внутри сущности, которая помещается в CMI модуля, является ошибкой. Однако в инициализаторе переменной или в теле невстраиваемой функции такое обращение не считается раскрытием, и ошибка не выдаётся.

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

Этот флаг включается параметром -Wextra.

-Wno-terminate (C++ and Objective-C++ only)

Отключить предупреждение о выражении throw, которое немедленно приводит к вызову terminate.

-Wno-vexing-parse (C++ and Objective-C++ only)

Предупреждать о синтаксической неоднозначности, известной как «самый коварный разбор». Предупреждение выдаётся, когда объявление выглядит как определение переменной, но по правилам языка C++ должно интерпретироваться как объявление функции. Например:

void f(double a) {
  int i();        // extern int i (void);
  int n(int(a));  // extern int n (int);
}

Ещё один пример:

struct S { S(int); };
void f(double a) {
  S x(int(a));   // extern struct S x (int);
  S y(int());    // extern struct S y (int (*) (void));
  S z();         // extern struct S z (void);
}

В предупреждении будут предложены способы устранения такой неоднозначности; например, можно убрать круглые скобки или заменить их фигурными.

Это предупреждение включено по умолчанию.

-Wno-class-conversion (C++ and Objective-C++ only)

Не выдавать предупреждение, если функция преобразования преобразует объект в тот же тип, в базовый класс этого типа или в void; такая функция преобразования никогда не будет вызвана.

-Wvolatile (C++ and Objective-C++ only)

Предупреждать об устаревшем использовании квалификатора volatile. Сюда относятся постфиксные и префиксные выражения ++ и -- для типов с квалификатором volatile, простые присваивания, в которых левый операнд — неклассовый тип с квалификатором volatile, составные присваивания, в которых левый операнд — неклассовый тип с квалификатором volatile, тип возвращаемого значения функции с квалификатором volatile, тип параметра с квалификатором volatile, а также структурные привязки типа с квалификатором volatile. Такое использование объявлено устаревшим в C++20.

По умолчанию включено с -std=c++20. До -std=c++20 включается явно с помощью -Wdeprecated.

-Waligned-new

Предупреждать о выражении new для типа, требующего выравнивания, превышающего alignof(std::max_align_t), если при этом используется функция выделения памяти без явного параметра выравнивания. Этот параметр включается с помощью -Wall.

Обычно предупреждение выдаётся только для глобальных функций выделения памяти, но -Waligned-new=all также включает предупреждения для функций выделения памяти — членов класса.

-Wno-placement-new
-Wplacement-new=n

Предупреждать о выражениях placement new с неопределённым поведением, например о создании объекта в буфере, размер которого меньше размера типа объекта. Например, приведённое ниже выражение placement new диагностируется, поскольку пытается создать массив из 64 целых чисел в буфере размером всего 64 байта.

char buf [64];
new (buf) int[64];

Это предупреждение включено по умолчанию.

-Wplacement-new=1

Это уровень предупреждения по умолчанию для -Wplacement-new. На этом уровне предупреждение не выдаётся для некоторых конструкций со строго неопределённым поведением, которые GCC допускает как расширения для совместимости с устаревшим кодом. Например, следующее выражение new на этом уровне не диагностируется, хотя согласно стандарту C++ оно имеет неопределённое поведение, поскольку выполняет запись за концом массива из одного элемента.

struct S { int n, a[1]; };
S *s = (S *)malloc (sizeof *s + 31 * sizeof s->a[0]);
new (s->a)int [32]();
-Wplacement-new=2

На этом уровне, помимо диагностики всех тех же конструкций, что и на уровне 1, также выдаётся диагностика для выражений placement new, создающих объект в последнем члене структуры, тип которого — массив из одного элемента, а размер меньше размера создаваемого объекта. Предыдущий пример был бы диагностирован, но в следующей конструкции используется расширение для массивов гибких членов, чтобы избежать предупреждения на уровне 2.

struct S { int n, a[]; };
S *s = (S *)malloc (sizeof *s + 32 * sizeof s->a[0]);
new (s->a)int [32]();
-Wcatch-value
-Wcatch-value=n (C++ and Objective-C++ only)

Предупреждать об обработчиках catch, которые не перехватывают исключение по ссылке. С параметром -Wcatch-value=1 (или просто -Wcatch-value) выдавать предупреждения о полиморфных типах классов, перехватываемых по значению. С параметром -Wcatch-value=2 предупреждать обо всех типах классов, перехватываемых по значению. С параметром -Wcatch-value=3 предупреждать обо всех типах, перехватываемых не по ссылке. -Wcatch-value включается параметром -Wall.

-Wconditionally-supported (C++ and Objective-C++ only)

Предупреждать о конструкциях с условной поддержкой (C++11 [intro.defs]).

-Wno-defaulted-function-deleted (C++ and Objective-C++ only)

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

-Wno-delete-incomplete (C++ and Objective-C++ only)

Не предупреждать при удалении указателя на неполный тип, что может привести к неопределённому поведению во время выполнения. Это предупреждение включено по умолчанию.

-Wextra-semi (C++, Objective-C++ only)

Предупреждать об избыточных точках с запятой. Существует несколько контекстов, в которых может появиться лишняя точка с запятой. Один из них — точка с запятой после определений функций внутри класса; она допустима во всех диалектах C++ (и никогда не вызывает pedwarn):

struct S {
  void foo () {};
};

Другой случай — лишняя точка с запятой на уровне пространства имён, допустимая начиная с C++11 (поэтому в C++98 она вызывает pedwarn):

struct S {
};
;

Ещё один случай — лишняя точка с запятой в определениях классов, допустимая начиная с C++11 (поэтому в C++98 она вызывает pedwarn):

struct S {
  int a;
  ;
};
-Wno-global-module (C++ and Objective-C++ only)

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

-Wno-inaccessible-base (C++, Objective-C++ only)

Этот параметр управляет предупреждениями о недоступности базового класса в производном от него классе из-за неоднозначности. Предупреждение включено по умолчанию. Обратите внимание: предупреждение о неоднозначных виртуальных базовых классах включается параметром -Wextra.

struct A { int a; };

struct B : A { };

struct C : B, A { };
-Wno-inherited-variadic-ctor

Подавлять предупреждения об использовании наследуемых конструкторов C++11, если унаследованный базовый класс имеет вариадический конструктор C; по умолчанию предупреждение включено, поскольку многоточие не наследуется.

-Wno-invalid-offsetof (C++ and Objective-C++ only)

Подавлять предупреждения при применении макроса offsetof к типу, не являющемуся POD. Согласно стандарту ISO C++ 2014 года применение offsetof к типу, не имеющему стандартного расположения, приводит к неопределённому поведению. Однако в существующих реализациях C++ offsetof обычно даёт осмысленные результаты. Этот флаг предназначен для пользователей, которые понимают, что пишут непереносимый код, и намеренно решили игнорировать соответствующее предупреждение.

Ограничения на offsetof могут быть смягчены в будущей версии стандарта C++.

-Wsized-deallocation (C++ and Objective-C++ only)

Предупреждать об определении функции освобождения памяти без указания размера

void operator delete (void *) noexcept;
void operator delete[] (void *) noexcept;

без определения соответствующей функции освобождения памяти с указанием размера

void operator delete (void *, std::size_t) noexcept;
void operator delete[] (void *, std::size_t) noexcept;

или наоборот. Включается параметром -Wextra вместе с -fsized-deallocation.

-Wsuggest-final-types

Предупреждать о типах с виртуальными методами, для которых качество кода улучшилось бы, если бы тип был объявлен с помощью спецификатора C++11 final или, если возможно, объявлен в анонимном пространстве имён. Это позволяет GCC выполнять более агрессивную девиртуализацию полиморфных вызовов. Это предупреждение эффективнее при оптимизации на этапе компоновки, когда сведения о графе иерархии классов полнее.

-Wsuggest-final-methods

Предупреждать о виртуальных методах, для которых качество кода улучшилось бы, если бы метод был объявлен с помощью спецификатора C++11 final или, если возможно, его тип был объявлен в анонимном пространстве имён либо со спецификатором final. Это предупреждение эффективнее при оптимизации на этапе компоновки, когда сведения о графе иерархии классов полнее. Рекомендуется сначала рассмотреть предложения параметра -Wsuggest-final-types, а затем пересобрать программу с новыми аннотациями.

-Wsuggest-override

Предупреждать о переопределении виртуальных функций, не помеченных ключевым словом override.

-Wno-conversion-null (C++ and Objective-C++ only)

Не предупреждать о преобразованиях между NULL и типами, не являющимися указателями. -Wconversion-null включён по умолчанию.

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

Spec-Zone.ru

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