Как я могу заставить gcc предупредить меня о "int i = i;" - PullRequest
0 голосов
/ 25 сентября 2018

Простая программа:

int main()
{
    long i = i;

    return 0;
}

Компиляция как C не дает ошибок и предупреждений.

$ gcc -Wall -Wextra -pedantic 1.c

Компиляция как C ++ выдает предупреждение:

$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
  long i = i;

В обоих случаях переменная i кажется равной 0, хотя в c ++ она может быть неинициализирована.Я действительно сделал такую ​​опечатку в одной из своих функций, и мне было довольно сложно ее найти.Что я могу сделать, чтобы избежать этого?Я бы ожидал, по крайней мере, предупреждение.Более того, Clang не выдает никаких предупреждений ни в одном из случаев (c или c ++).Есть ли конкретная часть стандарта, которая говорит что-нибудь об этом поведении?

Редактировать: Попробовав нечто подобное:

$ cat 1.c
int main(void)
{
    int k = k + 0;
    int i = i + 1;
    return 0;
}

Предупреждение (в C) генерируется только для "i".

$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
  int i = i + 1;

Ответы [ 3 ]

0 голосов
/ 25 сентября 2018

Для компиляции программ на Си GCC вам необходимо добавить флаг компилятора -Winit-self.(Вам также нужно -Wall или -Wuninitialized, см. Ниже.) Для GCC, компилирующих программы на C ++, этот флаг подразумевается -Wall, но для C он должен быть указан явно;он также не является частью -Wextra.

Для Clang ситуация несколько интереснее.В фрагменте в OP Clang не производит никакой диагностики.Однако с помощью немного отличающегося фрагмента, представленного в руководстве GCC ниже, предоставляется диагностика:

int f() {
  int i = i;
  return i;
}

Разница в том, что в приведенном выше фрагменте фактически используется (неинициализированное) значение i.По-видимому, в исходном коде Clang обнаружил, что переменная была бесполезна, и удалил ее как мертвый код перед применением диагностики.

В Clang диагностика запускается с помощью -Wuninitialized, которая активируется -Wall какв GCC.


Вот выдержка из руководства GCC:

-Winit-self (только C, C ++, Objective-C и Objective-C ++)

Предупреждать о неинициализированных переменных, которые инициализируются сами по себе.Обратите внимание, что эту опцию можно использовать только с опцией -Wuninitialized.

Например, GCC предупреждает о неинициализации i в следующем фрагменте, только если было указано -Winit-self:

        int f()
          {
            int i = i;
            return i;
          }

Это предупреждение активируется -Wall в C ++.

Как указывает выдержка, -Wuninitialized также требуется.Как в C, так и в C ++ -Wall означает -Wuninitialized.Однако обратите внимание, что многие неинициализированные варианты использования не будут обнаружены, если не будет запрошен некоторый уровень оптимизации.(Насколько я знаю, это не относится к -Winit-self. Его можно обнаружить без оптимизации.)


Раздражительно, когда вы отмечаете вопрос как дубликат, ранее отмеченные дубликатыисчезают.Я не пометил это, потому что ни один из дубликатов фактически не ответил на вопрос в теле;Я также отредактировал заголовок.

Для справки, вот оригинальные дубликаты, которые могут представлять интерес:

0 голосов
/ 25 сентября 2018

Комбинация -Wall -Winit-self, кажется, добавляет эту диагностику:

$ gcc -Wall      -Winit-self t.c
t.c: In function ‘main’:
t.c:3:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
     long i = i;
          ^
0 голосов
/ 25 сентября 2018

Это в основном:

int i;
i = i;

, в котором i является неинициализированным значением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...