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-deleteGCC может предполагать, что вызовы заменяемых глобальных операторов из выражений new или delete либо из вызовов__builtin_operator_newили__builtin_operator_deleteне читают и не изменяют глобальные переменные или переменные, адрес которых может быть передан операторам (глобальное состояние; за исключениемerrnoдля операторовnewиnew[]). Это позволяет выполнять большинство оптимизаций через такие вызовы и соответствует поведению операторов, предоставленных реализацией, если только в коде не наблюдаются детали реализацииmallocили не используются перехватчикиmalloc. Однако это предположение может быть неверным, если программа заменяет эти операторы. Такое поведение включено по умолчанию. При параметре-fno-assume-sane-operators-new-deleteGCC должен предполагать, что все эти вызовы (из выражений 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_continueneverabort-
Этот контракт проверяется. При его нарушении вызывается обработчик нарушения. Если обработчик возвращает управление, вызывается
std::terminate. check_maybe_continuemaybeЭтот контракт проверяется. При его нарушении вызывается обработчик нарушения. Если обработчик возвращает управление, выполнение продолжается обычным образом.
-
-
-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-escalationfне повышается доconsteval, и поскольку вызов функции constevalid(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:
- Он устанавливает видимость по умолчанию в
hidden, как и -fvisibility=hidden. - Типы, но не их члены, по умолчанию не являются скрытыми.
- Правило одного определения ослабляется для типов без явных спецификаций видимости, определенных более чем в одном разделяемом объекте: такие объявления допускаются, если они допускались бы при отключенном параметре.
В новом коде лучше использовать -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