Spec-Zone.ru › GCC 9

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:

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

В новом коде лучше использовать -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

Spec-Zone.ru

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