Заставьте GCC выдавать ошибку, когда присвоение (заключенное в скобки) используется в качестве значения истинности

#c #gcc

Вопрос:

Я пытаюсь найти флаг компилятора GCC, который заставил бы GCC отказаться от компиляции следующего кода:

 # include <stdio.h>

int main()
{
    int x = 1;

    if( (x = 10) ) {
        printf("x is 10");
    } else {
        printf("x is not 10");
    }
    return 0;
}
 

Приведенный выше код будет скомпилирован без предупреждений:

gcc -Wall -Werror -O3 -o x.exe x.c

В частности, я хочу, чтобы GCC вырвало на линии if( (x = 10) ) . Если я удалю внутренние скобки, GCC сломается из-за -Werror

 gcc -Wall -Werror -O3 -o x.exe x.c
x.c: In function 'main':
x.c:7:9: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
     if( x = 10 ) {
         ^
cc1.exe: all warnings being treated as errors
 

То, что я ищу, — это способ заставить GCC отказаться от компиляции кода, даже если присутствуют скобки.

Спасибо!

Комментарии:

1. Я не думаю, что ты сможешь. Дополнительные скобки-это способ, которым вы сообщаете GCC, что он не должен предупреждать о назначении. И если он не предупреждает, он не может превратить предупреждение в ошибку с помощью -Werror

2. @Someprogrammerdude, нет, я хочу прямо противоположного: я хочу, чтобы GCC ОТКАЗАЛСЯ от компиляции, если кто-то забыл добавить второе = в сравнении.

3. Что ж, это как синтаксически, так и семантически корректно, поскольку присваивание-это выражение, а условием может быть любое выражение. Компилятор не должен запрещать такой код. Как вы уже упоминали, это только то, с чем инструмент статического анализа сможет справиться так, как вы хотите.

4. @Someprogrammerdude, но побочные эффекты этой дополнительной скобки, отключающей предупреждение, о котором вы явно просите, пагубны. GCC «скрывает» назначение-в-случае, если при добавлении дополнительных скобок это ПЛОХАЯ идея .

5. @AndrewHenle Верно, но, с другой стороны, иногда вы хотите выполнить задание в условии, а затем не хотите отключать его глобально (используя флаги при построении) или загромождать код прагматиками, специфичными для компилятора, и тому подобное.

Ответ №1:

Похоже, нет никакого способа убедить GCC сделать это. -Wall -Wextra не предупреждает для вашего примера кода, и я не видел никаких других вариантов предупреждения, которые казались бы уместными. (Как отмечалось в комментариях, по замыслу GCC, как правило, единственный способ заставить его отклонить законный код в противном случае-это найти опцию предупреждения, которую запускает код, а затем использовать -Werror для обновления предупреждения до ошибки.)

В качестве еще одной точки данных clang предлагает довольно похожий набор предупреждений, как GCC, и у него есть бонус в виде -Weverything опции, которая включает каждое предупреждение, которое он предоставляет. (Было бы неплохо, если бы у GCC тоже была такая вещь.) Но clang -Weverything также не дает никаких предупреждений для вашего кода. Это кажется довольно веским доказательством того, что никто в этих сообществах не реализовал предупреждение для кода, подобного вашему.

Я согласен, что это кажется чем-то полезным, поэтому, возможно, стоит подать запрос на функцию GCC и/или clang (или посмотреть, есть ли у кого-то уже).