GCC команды · 5 min read · Jan 22, 2026
Необычные, но полезные параметры командной строки GCC - часть 2
Компилятор gcc предлагает, казалось бы, бесконечный список параметров командной строки. Конечно, никто не использует и не имеет экспертизы по всем из них, но есть определенная группа, которую каждый пользователь gcc должен - если не обязан - знать. В то время как некоторые из них часто используются, другие немного необычны, но не менее полезны.
В этой серии статей мы сосредоточимся на некоторых из этих необычных, но полезных параметров командной строки gcc и уже рассмотрели несколько из них в части 1.
Если вы помните, в начале первой части этой серии учебников я кратко упомянул, что параметр -Wall, который разработчики обычно используют для генерации предупреждений, не охватывает некоторые специфические предупреждения. Если вы не знаете об этих предупреждениях и не имеете представления о том, как их включить, не беспокойтесь, так как мы объясним все это подробно в этой статье.
Кроме этого, мы также рассмотрим параметр предупреждения gcc, связанный с переменными с плавающей точкой, а также как лучше управлять параметрами командной строки gcc, если список становится большим.
Но прежде чем мы продолжим, пожалуйста, имейте в виду, что все примеры, команды и инструкции, упомянутые в этом учебнике, были протестированы на Ubuntu 16.04 LTS, и версия gcc, которую мы использовали, - 5.4.0.
** Включить предупреждения, которые не охватываются -Wall
Хотя параметр -Wall компилятора gcc охватывает большинство флагов предупреждений, есть некоторые, которые остаются отключенными. Чтобы включить их, используйте параметр -Wextra.
Например, взгляните на следующий код:
#include
#include
int main()
{
int i=0;
/* ...
some code here
...
*/
if(i);
return 1;
return 0;
} Я случайно поставил точку с запятой после условия ‘if’. Теперь, когда код был скомпилирован с использованием следующей команды gcc, предупреждение не было выдано.
gcc -Wall test.c -o testНо когда был использован параметр -Wextra:
gcc -Wall -Wextra test.c -o testБыло выдано предупреждение:
test.c: In function ‘main’:
test.c:10:8: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
if(i);Как видно из предупреждения, показанного выше, параметр -Wextra внутренне включил флаг -Wempty-body, который в свою очередь обнаружил подозрительный код и выдал предупреждение. Вот полный список флагов предупреждений, включенных этим параметром:
-Wclobbered, -Wempty-body, -Wignored-qualifiers, -Wmissing-field-initializers, -Wmissing-parameter-type (только C), -Wold-style-declaration (только C), -Woverride-init, -Wsign-compare, -Wtype-limits, -Wuninitialized, -Wunused-parameter (только с -Wunused или -Wall) и -Wunused-but-set-parameter (только с -Wunused или -Wall).
Если вы хотите узнать, что делают вышеупомянутые флаги, обратитесь к странице man gcc.
Двигаясь дальше, параметр -Wextra также выдает предупреждения в следующих случаях:
- Указатель сравнивается с целым нулем с помощью <, <=, > или >=
- (только C++) Перечислитель и не перечислитель оба появляются в условном выражении.
- (только C++) Неоднозначные виртуальные базовые классы.
- (только C++) Индексация массива, который был объявлен как register.
- (только C++) Получение адреса переменной, которая была объявлена как register.
- (только C++) Базовый класс не инициализируется в конструкторе копирования производного класса.
Включить предупреждение для значений с плавающей точкой в сравнении на равенство
Как вы, возможно, уже знаете, никогда не следует проверять на точное равенство значения с плавающей точкой (не знали об этом - прочитайте часто задаваемые вопросы, связанные с сравнением с плавающей точкой, здесь). Но даже если вы случайно сделаете это, выдает ли компилятор gcc какое-либо предупреждение или ошибку? Давайте проверим:
Вот код, который сравнивает переменные с плавающей точкой с использованием оператора ==:
#include
void compare(float x, float y)
{
if(x == y)
{
printf("\n EQUAL \n");
}
}
int main(void)
{
compare(1.234, 1.56789);
return 0;
} А вот команда gcc (содержащая как -Wall, так и -Wextra), использованная для компиляции этого кода:
gcc -Wall -Wextra test.c -o testК сожалению, вышеуказанная команда не выдает никаких предупреждений, связанных с сравнением с плавающей точкой. Быстрый взгляд на страницу man GCC показывает, что существует специальный параметр -Wfloat-equal, который следует использовать в этих сценариях.
Вот команда с этим параметром:
gcc -Wall -Wextra -Wfloat-equal test.c -o testА вот вывод, который она произвела:
test.c: In function ‘compare’:
test.c:5:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
if(x == y)Итак, как вы видите в приведенном выше выводе, параметр -Wfloat-equal заставил gcc выдать предупреждение, связанное с сравнением с плавающей точкой.
Вот что страница man gcc говорит об этом параметре:
Идея заключается в том, что иногда удобно (для программиста) рассматривать значения с плавающей точкой как приближения к бесконечно точным вещественным числам. Если вы делаете это, то вам нужно вычислить (анализируя код или каким-либо другим способом) максимальную или вероятную максимальную ошибку, которую вводит вычисление, и учитывать это при выполнении сравнений (и при выводе, но это другая проблема). В частности, вместо того, чтобы проверять на равенство, вам следует проверить, имеют ли два значения перекрывающиеся диапазоны; и это делается с помощью реляционных операторов, поэтому сравнения на равенство, вероятно, ошибочны.Как лучше управлять параметрами командной строки gcc
Если список параметров командной строки, которые вы используете в вашей команде gcc, становится больше и труднее управлять, вы можете поместить его в текстовый файл и передать имя этого файла в качестве аргумента команде gcc. Для этого вам нужно будет использовать параметр @file.
Например, если ваша команда gcc выглядит следующим образом:
gcc -Wall -Wextra -Wfloat-equal test.c -o testТо вы можете поместить три параметра, связанные с предупреждениями, в файл с именем, скажем, ‘gcc-options’:
$ cat gcc-options
-Wall -Wextra -Wfloat-equalИ ваша команда gcc станет менее загроможденной и легкой для управления:
gcc @gcc-options test.c -o testВот что страница man gcc говорит о @file:
Читать параметры командной строки из файла. Прочитанные параметры вставляются на место оригинального параметра @file. Если файл не существует или не может быть прочитан, то параметр будет рассматриваться буквально и не будет удален.
Параметры в файле разделяются пробелами. Символ пробела может быть включен в параметр, окружив весь параметр либо одинарными, либо двойными кавычками. Любой символ (включая обратный слэш) может быть включен, предварительно указав символ, который нужно включить, с помощью обратного слэша. Сам файл может содержать дополнительные параметры @file; любые такие параметры будут обрабатываться рекурсивно.Заключение
Итак, мы рассмотрели всего 5 необычных, но полезных параметров командной строки gcc в этой серии учебников: -save-temps, -g, -Wextra, -Wfloat-equal и @file. Обязательно уделите время практике каждого из них и не забудьте ознакомиться со всеми деталями, которые страница man gcc предлагает о них.
Знаете ли вы или используете другие такие полезные параметры командной строки gcc и хотите поделиться ими с миром? Оставьте все детали в комментариях ниже.
Get new posts in your inbox
No spam. Unsubscribe anytime.