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 C++ ABI. По умолчанию используется версия 0.
Версия 0 соответствует версии, наиболее близкой к спецификации C++ ABI. Поэтому ABI, полученный с использованием версии 0, будет меняться в разных версиях G++, по мере исправления ошибок ABI.
Версия 1 — это версия C++ ABI, впервые появившаяся в G++ 3.2.
Версия 2 — это версия C++ ABI, впервые появившаяся в G++ 3.4 и была по умолчанию в G++ 4.9.
Версия 3 исправляет ошибку в обработке постоянного адреса как аргумента шаблона.
Версия 4, впервые появившаяся в G++ 4.5, реализует стандартную обработку векторизованных типов.
Версия 5, впервые появившаяся в G++ 4.6, исправляет обработку атрибутов const/volatile для указателей на функции, decltype обычного decl и использование параметра функции в объявлении другого параметра.
Версия 6, впервые появившаяся в G++ 4.7, исправляет поведение продвижения C++11 scoped перечислений и обработку пакетов аргументов шаблонов, const/static_cast, префиксные ++ и –, а также функцию области класса, используемую как аргумент шаблона.
Версия 7, появившаяся в G++ 4.8, обрабатывает nullptr_t как встроенный тип и исправляет обработку лямбда-выражений в области аргумента по умолчанию.
Версия 8, появившаяся в G++ 4.9, исправляет поведение подстановки типов функций с квалификаторами функций.
Версия 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.
См. также -Wabi.
-fabi-compat-version=n-
На целевых платформах, поддерживающих сильные псевдонимы, G++ обходит изменения обработки, создавая псевдоним с правильным именем обработки при определении символа с неправильным именем обработки. Этот переключатель указывает, какую версию ABI использовать для псевдонима.
С -fabi-version=0 (по умолчанию) это по умолчанию 11 (совместимость с GCC 7). Если явно выбрана другая версия 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.
-fchar8_t-fno-char8_t-
Включить поддержку
char8_tв соответствии с C++2a. Это включает добавление нового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.
char ca[] = u8"xx"; // error: char-array initialized from wide // string 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++ Extensions for Concepts Technical Specification, ISO 19217 (2015), которая позволяет использовать код, подобный
template <class T> concept bool Addable = requires (T t) { t + t; }; template <Addable T> T add (T a, T b) { return a + b; } -fconstexpr-depth=n-
Установить максимальную глубину вложенных вычислений для C++11 constexpr функций до n. Ограничение необходимо для обнаружения бесконечной рекурсии во время вычисления константных выражений. Минимальное значение, заданное стандартом, равно 512.
-fconstexpr-loop-limit=n-
Установить максимальное число итераций цикла для C++14 constexpr функций до n. Ограничение необходимо для обнаружения бесконечных циклов во время вычисления константных выражений. По умолчанию значение равно 262144 (1<<18).
-fconstexpr-ops-limit=n-
Установить максимальное число операций в рамках одного constexpr вычисления до n. Даже если число итераций в отдельном цикле ограничено вышеуказанным значением, если есть несколько вложенных циклов, каждый из которых имеет много итераций, но всё ещё меньше указанного значения, или если в теле какого-либо цикла или даже вне цикла слишком много выражений, которые нужно оценить, итоговое constexpr вычисление может занять слишком много времени. По умолчанию значение равно 33554432 (1<<25).
-fdeduce-init-list-
Включить вывод типа параметра шаблона как
std::initializer_listиз списка инициализаторов в фигурных скобках, т.е.template <class T> auto forward(T t) -> decltype (realfn (t)) { return realfn (t); } void f() { forward({1,2}); // call forward<std::initializer_list<int>> }Этот вывод был реализован как возможное расширение первоначально предложенной семантики для C++11 стандарта, но не был частью окончательного стандарта, поэтому он отключён по умолчанию. Этот параметр устарел и может быть удалён в будущих версиях G++.
-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.
-fno-gnu-keywords-
Не распознавать
typeofкак ключевое слово, чтобы код мог использовать это слово как идентификатор. Вы можете использовать ключевое слово__typeof__вместо него. Этот параметр подразумевается строгими диалектами ISO C++: -ansi, -std=c++98, -std=c++11 и т.д. -fno-implicit-templates-
Никогда не генерировать код для нелинейных шаблонов, которые неявно экземпляризируются (т.е. используются); генерировать код только для явных экземпляризаций. Если вы используете этот параметр, вы должны позаботиться о структуре вашего кода, чтобы включить все необходимые явные экземпляризации, чтобы избежать появления неопределённых символов во время линковки. См. Экземпляризацию шаблонов для получения дополнительной информации.
-fno-implicit-inline-templates-
Не генерировать код для неявных экземпляризаций встроенных шаблонов. По умолчанию обрабатывать встроенные функции по-разному, чтобы компиляции с оптимизацией и без неё требовался один и тот же набор явных экземпляризаций.
-fno-implement-inlines-
Для экономии места не генерировать вне-строчные копии встроенных функций, управляемых
#pragma implementation. Это приводит к ошибкам линковщика, если эти функции не встроены повсюду, где они вызываются. -fms-extensions-
Отключить предупреждения Wpedantic о конструкциях, используемых в MFC, таких как неявные int и получение указателя на член функции через нестандартный синтаксис.
-fnew-inheriting-ctors
-
Включить корректировку P0136 к семантике наследования конструкторов C++11. Это часть 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, чтобы уменьшить или устранить размер текста по сравнению с функцией без спецификации исключения. Если функция имеет локальные переменные типов с нетривиальными деструкторами, спецификация исключения фактически уменьшает размер функции, потому что обработка исключений для этих переменных может быть оптимизирована. Семантический эффект заключается в том, что исключение, брошенное из функции с такой спецификацией исключения, приводит к вызовуterminateвместоunexpected. -fno-operator-names-
Не рассматривать ключевые слова имён операторов
and,bitand,bitor,compl,not,orиxorкак синонимы ключевых слов. -fno-optional-diags-
Отключить диагностику, которую стандарт гласит, что компилятор не должен выдавать. В настоящее время единственная такая диагностика, выдаваемая G++, — это диагностика для имени, имеющего несколько значений внутри класса.
-fpermissive-
Снизить некоторые диагностики о несоответствующем коде с ошибок до предупреждений. Таким образом, использование -fpermissive позволяет компилировать некоторый несоответствующий код.
-fno-pretty-templates-
Когда сообщение об ошибке относится к специализации шаблона функции, компилятор обычно печатает сигнатуру шаблона, за которой следуют аргументы шаблона и любые определения типов или имена типов в сигнатуре (например,
void f(T) [with T = int]вместоvoid f(int)), чтобы было ясно, какой шаблон участвует. Когда сообщение об ошибке относится к специализации шаблона класса, компилятор опускает любые аргументы шаблона, соответствующие аргументам шаблона по умолчанию для этого шаблона. Если какое-либо из этих поведений усложняет понимание сообщения об ошибке, а не упрощает, вы можете использовать -fno-pretty-templates для их отключения. -frepo-
Включить автоматическую инстанциацию шаблона во время линковки. Этот параметр также подразумевает -fno-implicit-templates. См. Инстанциацию шаблонов для получения дополнительной информации.
-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-
Оценивать доступ к членам, индексирование массивов и сдвиговые выражения в порядке слева направо, а присваивание в порядке справа налево, как принято для C++17. Включено по умолчанию с -std=c++17. -fstrong-eval-order=some включает только порядок доступа к членам и сдвиговых выражений и является по умолчанию без -std=c++17.
-ftemplate-backtrace-limit=n-
Установить максимальное количество заметок о шаблоне инстанцирования для одного предупреждения или ошибки на n. Значение по умолчанию 10.
-ftemplate-depth=n-
Установить максимальную глубину инстанциации для шаблонов классов на n. Ограничение глубины инстанциации шаблонов необходимо для обнаружения бесконечных рекурсий во время инстанциации шаблонов классов. Программы, соответствующие ANSI/ISO C++, не должны полагаться на максимальную глубину, большую чем 17 (изменено на 1024 в C++11). Значение по умолчанию 900, так как компилятор может исчерпать память стека, прежде чем достигнет 1024 в некоторых ситуациях.
-fno-threadsafe-statics-
Не генерировать дополнительный код для использования процедур, указанных в C++ ABI для безопасной по отношению к потокам инициализации локальных статических переменных. Вы можете использовать этот параметр, чтобы немного уменьшить размер кода в коде, который не требует безопасности по отношению к потокам.
-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 и не требуют косвенного обращения через PLT при использовании в DSO. Включение этого параметра может оказать существенное влияние на время загрузки и линковки DSO, так как это значительно уменьшает размер динамической таблицы экспорта, когда библиотека активно использует шаблоны.Поведение этого переключателя не совсем такое же, как непосредственное помечание методов как скрытых, так как это не влияет на статические переменные, локальные для функции, или не заставляет компилятор вывести, что функция определена только в одном общем объекте.
Вы можете явно пометить метод, чтобы отменить действие переключателя для этого метода. Например, если вы хотите сравнить указатели на определённый встроенный метод, вы можете пометить его как имеющий видимость по умолчанию. Пометка содержащего класса явной видимостью не имеет эффекта.
Явно инстанцированные внутренние методы не затрагиваются этим параметром, поскольку их связь может иначе пересекать границу общей библиотеки. См. Инстанциацию шаблонов.
-fvisibility-ms-compat-
Этот флаг пытается использовать настройки видимости, чтобы сделать модель связи C++ GCC совместимой с моделью связи Microsoft Visual Studio.
Флаг вносит следующие изменения в модель связи GCC:
- Он устанавливает видимость по умолчанию на
hidden, как -fvisibility=hidden. - Типы, но не их члены, не скрываются по умолчанию.
- Правило одной дефиниции ослаблено для типов без явных спецификаций видимости, определённых в более чем одном общем объекте: такие объявления разрешены, если они разрешены, когда этот параметр не используется.
В новом коде лучше использовать -fvisibility=hidden и экспортировать те классы, которые предназначены для внешней видимости. К сожалению, возможно, что код полагается, возможно случайно, на поведение Visual Studio.
Среди последствий этих изменений — то, что статические члены данных одного типа с одинаковым именем, но определённые в разных общих объектах, отличаются, поэтому изменение одного не изменяет другого; и то, что указатели на члены функции, определённые в разных общих объектах, могут не сравниваться как равные. Когда данный флаг используется, нарушение правила одной дефиниции (ODR) заключается в определении типов с одинаковым именем по-разному.
- Он устанавливает видимость по умолчанию на
-fno-weak-
Не использовать поддержку слабых символов, даже если она предоставлена линковщиком. По умолчанию G++ использует слабые символы, если они доступны. Этот параметр существует только для тестирования и не должен использоваться конечными пользователями; он приводит к худшему коду и не имеет преимуществ. Этот параметр может быть удален в будущих версиях G++.
-nostdinc++-
Не искать заголовочные файлы в стандартных директориях, специфичных для C++, но по-прежнему искать в других стандартных директориях. (Этот параметр используется при построении библиотеки C++.)
Кроме того, эти параметры оптимизации, предупреждений и генерации кода имеют значение только для программ C++:
-Wabi (C, Objective-C, C++ and Objective-C++ only)-
Предупреждение при генерации кода G++, который, вероятно, несовместим с нейтральным по отношению к поставщику C++ ABI. Поскольку G++ теперь по умолчанию обновляет ABI с каждой основной версией, обычно -Wabi будет выдавать предупреждение только в том случае, если в последующих выпусках добавляется проверка на проблему ABI, обнаруженную после первоначального выпуска. -Wabi будет предупреждать о большем количестве вещей, если выбрана более старая версия ABI (с помощью -fabi-version=n).
-Wabi также может использоваться с явным номером версии, чтобы предупреждать о совместимости с определенным уровнем -fabi-version, например, -Wabi=2 для предупреждения о изменениях по отношению к -fabi-version=2.
Хотя предприняты усилия для предупреждения обо всех таких случаях, вероятно, существуют некоторые случаи, которые не предупреждаются, даже если G++ генерирует несовместимый код. Также могут быть случаи, когда предупреждения генерируются, даже если сгенерированный код совместим.
Вы должны переписать свой код, чтобы избежать этих предупреждений, если вас беспокоит тот факт, что код, сгенерированный G++, может не быть двоично совместим с кодом, сгенерированным другими компиляторами.
Известные несовместимости в -fabi-version=2 (который был по умолчанию от GCC 3.4 до 4.9) включают:
- Шаблон с параметром шаблона нетипа типа ссылки был неправильно замаскирован:
extern int N; template <int &> struct S {}; void n (S<N>) {2}Это было исправлено в -fabi-version=3.
- Типы векторов SIMD, объявленные с использованием
__attribute ((vector_size)), были замаскированы нестандартным способом, что не позволяет перегружать функции, принимающие векторы разного размера.Замена маскирования была изменена в -fabi-version=4.
-
__attribute ((const))иnoreturnбыли замаскированы как квалификаторы типов, иdecltypeпростой декларации была убрана.Эти проблемы с маскированием были исправлены в -fabi-version=5.
- Областные перечисления, переданные в качестве аргументов функции с переменным числом аргументов, повышаются, как неопределённые перечисления, что приводит к
va_argжаловаться. На большинстве целевых платформ это фактически не влияет на ABI передачи параметров, так как нет способа передать аргумент, меньшийint.Также ABI изменил маскирование пакетов аргументов шаблона,
const_cast,static_cast, префиксный инкремент/декремент и функцию области класса, используемую как аргумент шаблона.Эти проблемы были исправлены в -fabi-version=6.
- Лямбды в области аргумента по умолчанию были замаскированы неправильно, и ABI изменил маскирование
nullptr_t.Эти проблемы были исправлены в -fabi-version=7.
- При маскировании типа функции с квалификаторами типа функции, неквалифицированный тип функции неправильно рассматривался как кандидат на подстановку.
Это было исправлено в -fabi-version=8, значение по умолчанию для GCC 5.1.
-
decltype(nullptr)неправильно имел выравнивание 1, что приводило к невыровненным доступам. Обратите внимание, что это не повлияло на ABI функции с параметромnullptr_t, так как параметры имеют минимальное выравнивание.Это было исправлено в -fabi-version=9, значение по умолчанию для GCC 5.2.
- Целеспецифические атрибуты, влияющие на идентичность типа, такие как вызовы ia32 на типе функции (stdcall, regparm и т. д.), не влияли на замаскированное имя, что приводило к конфликтам имён при использовании указателей на функции в качестве аргументов шаблона.
Это было исправлено в -fabi-version=10, значение по умолчанию для GCC 6.1.
Он также предупреждает об изменениях, связанных с psABI. Известные изменения psABI на данный момент включают:
- Для SysV/x86-64 союзы с
long doubleчленами передаются в памяти, как указано в psABI. Например:union U { long double ld; int i; };union Uвсегда передаётся в памяти.
- Шаблон с параметром шаблона нетипа типа ссылки был неправильно замаскирован:
-Wabi-tag (C++ and Objective-C++ only)-
Предупреждение, если тип с тегом ABI используется в контексте, который не имеет этого тега ABI. См. Атрибуты C++ для получения дополнительной информации об тегах ABI.
-Wctor-dtor-privacy (C++ and Objective-C++ only)-
Предупреждение, если класс кажется непригодным для использования, поскольку все конструкторы или деструкторы в этом классе являются закрытыми, и у него нет ни друзей, ни общедоступных статических функций-членов. Также предупреждение, если нет функций-членов, отличных от закрытых, и есть по крайней мере одна закрытая функция-член, которая не является конструктором или деструктором.
-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-init-list-lifetime (C++ and Objective-C++ only)-
Не выдавать предупреждений об использовании
std::initializer_list, которые, вероятно, приведут к висячим указателям. Поскольку базовый массив дляinitializer_listобрабатывается как обычный временный объект C++, легко непреднамеренно сохранить указатель на массив после окончания срока жизни массива. Например:- Если функция возвращает временный
initializer_list, или локальнуюinitializer_listпеременную, срок жизни массива заканчивается в конце оператора возврата, поэтому возвращаемое значение имеет висячий указатель. - Если выражение 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, указатель остается висячим к концу оператора объявления переменной.
- Если функция возвращает временный
-Wliteral-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обрабатывается как отдельный предпроцессорный токен.Кроме того, предупреждение, когда оператор пользовательского литерала объявляется с идентификатором суффикса литерала, который не начинается с нижнего подчеркивания. Идентификаторы суффиксов литералов, которые не начинаются с нижнего подчеркивания, зарезервированы для будущей стандартизации.
Это предупреждение включено по умолчанию.
-Wlto-type-mismatch-
Во время оптимизации в момент компоновки предупреждение о несоответствиях типов в глобальных объявлениях из разных единиц трансляции. Требуется включить -flto. Включено по умолчанию.
-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 оценивается как ложь из-за вызова функции, у которой нет спецификации исключения без выбрасывания (т. е.
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, является объектом класса, а запись в такой объект может обойти нетривиальный или удалённый конструктор или оператор присваивания копирования класса, нарушить правильность const или инкапсуляцию, или повредить указатели на виртуальные таблицы. Изменение представления таких объектов может нарушить инварианты, поддерживаемые функциями-членами класса. Например, вызовmemsetниже не определён, потому что он изменяет объект нетривиального класса, и поэтому диагностируется. Безопасный способ инициализировать или очистить хранилище таких типов объектов — использовать соответствующий конструктор или оператор присваивания, если он доступен.std::string str = "abc"; memset (&str, 0, sizeof str);
Опция -Wclass-memaccess включена опцией -Wall. Явное приведение указателя к объекту класса к
void *или к типу, который может быть безопасно обработан функцией обработки сырой памяти, подавляет предупреждение. -Wnon-virtual-dtor (C++ and Objective-C++ only)-
Предупреждение, когда класс имеет виртуальные функции и доступный невиртуальный деструктор в самом себе или в доступном полиморфном базовом классе, в этом случае возможно, но небезопасно удалять экземпляр производного класса через указатель на сам класс или базовый класс. Это предупреждение автоматически включено, если указана -Weffc++.
-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препятствует удалению копирования. Типичный сценарий, когда возможно удаление копирования, — это возврат в функции с типом возвращаемого значения класс, когда выражение, возвращаемое именем не-постоянного автоматического объекта, не является параметром функции и имеет тот же тип, что и тип возвращаемого значения функции.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.
-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, ...).
Следующие параметры -W… не затрагиваются параметром -Wall.
-Weffc++ (C++ and Objective-C++ only)-
Предупреждать о нарушениях следующих рекомендаций по стилю из серии книг Скотта Майерса «Effective C++»:
- Определить конструктор копирования и оператор присваивания для классов с динамически выделенной памятью.
- Предпочитать инициализацию присваиванию в конструкторах.
- Заставлять
operator=возвращать ссылку на*this. - Не пытаться возвращать ссылку, когда необходимо возвращать объект.
- Различать префиксные и постфиксные формы операторов инкремента и декремента.
- Никогда не перегружать
&&,||, или,.
Этот параметр также включает -Wnon-virtual-dtor, который также является одной из рекомендаций Effective C++. Однако проверка расширена, чтобы предупреждать о недостатке виртуального деструктора в доступных неполиморфных базовых классах.
При выборе этого параметра имейте в виду, что заголовочные файлы стандартной библиотеки не следуют всем этим рекомендациям; используйте ‘grep -v’ для фильтрации этих предупреждений.
-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)’, где имя друга является unqualified-id, могли интерпретироваться как конкретная специализация шаблонной функции; предупреждение существует для диагностики проблем совместимости и включено по умолчанию.
-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)-
Предупреждать, когда объявление функции скрывает виртуальные функции из базового класса. Например, в:
struct A { virtual void f(); }; struct B: public A { void f(int); };версия функции
fклассаAскрыта вB, и код вида:B* b; b->f();
не компилируется.
-Wno-pmf-conversions (C++ and Objective-C++ only)-
Отключить диагностику при преобразовании связанного указателя на член-функцию в обычный указатель.
-Wsign-promo (C++ and Objective-C++ only)-
Предупреждать, когда разрешение перегрузки выбирает продвижение от беззнакового или перечислимого типа к знакомому типу вместо преобразования в беззнаковый тип того же размера. Предыдущие версии G++ пытались сохранить беззнаковость, но стандарт предписывает текущее поведение.
-Wtemplates (C++ and Objective-C++ only)-
Предупреждать при обнаружении объявления первичного шаблона. Некоторые правила программирования не допускают шаблоны, и это может использоваться для принудительного соблюдения такого правила. Предупреждение неактивно внутри заголовочного файла системы, например, STL, поэтому можно по-прежнему использовать STL. Также можно инстанцировать или специализировать шаблоны.
-Wmultiple-inheritance (C++ and Objective-C++ only)-
Предупреждать при определении класса с несколькими прямыми базовыми классами. Некоторые правила программирования не допускают множественного наследования, и это может использоваться для принудительного соблюдения такого правила. Предупреждение неактивно внутри заголовочного файла системы, например, STL, поэтому можно по-прежнему использовать STL. Также можно определять классы, косвенно использующие множественное наследование.
-Wvirtual-inheritance-
Предупреждать при определении класса с виртуальным прямым базовым классом. Некоторые правила программирования не допускают множественного наследования, и это может использоваться для принудительного соблюдения такого правила. Предупреждение неактивно внутри заголовочного файла системы, например, STL, поэтому можно по-прежнему использовать STL. Также можно определять классы, косвенно использующие виртуальное наследование.
-Wnamespaces-
Предупреждать при открытии определения области имен. Некоторые правила программирования не допускают области имен, и это может использоваться для принудительного соблюдения такого правила. Предупреждение неактивно внутри заголовочного файла системы, например, STL, поэтому можно по-прежнему использовать STL. Также можно использовать директивы using и квалифицированные имена.
-Wno-terminate (C++ and Objective-C++ only)-
Отключить предупреждение об выражении throw, которое сразу приведет к вызову
terminate. -Wno-class-conversion (C++ and Objective-C++ only)-
Отключить предупреждение о случае, когда функция преобразования преобразует объект к тому же типу, к базовому классу этого типа или к void; такая функция преобразования никогда не будет вызвана.
Далее: Параметры диалектов Objective-C и Objective-C++, Предыдущее: Параметры диалекта C, Вверх: Вызов GCC [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/C_002b_002b-Dialect-Options.html