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 и хотите поделиться ими с миром? Оставьте все детали в комментариях ниже.

Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.