Как бороться с предупреждениями -Wconversion от GCC?

StackOverflow https://stackoverflow.com/questions/1643537

  •  10-07-2019
  •  | 
  •  

Вопрос

Я создаю свой проект с флагом предупреждения GCC -Wconversion.(gcc (Debian 4.3.2-1.1) 4.3.2) на 64-битной ОС/оборудовании GNU/Linux.Я нахожу это полезным для определения того, где я перепутал типы или потерял ясность относительно того, какие типы следует использовать.

Это не очень полезно в большинстве других ситуаций, которые активируют его предупреждения, и я спрашиваю, как мне с ними справиться:

enum { A = 45, B, C };   /* fine */

char a = A;              /* huh? seems to not warn about A being int. */
char b = a + 1;          /* warning converting from int to char */
char c = B - 2;          /* huh? ignores this *blatant* int too.*/
char d = (a > b ? b : c) /* warning converting from int to char */

В связи с неожиданными результатами вышеуказанных испытаний (случаи a и c) Я тоже прошу объяснить эти различия.

Редактировать:И не является ли это чрезмерным инженерным трудом — приводить все это к (char) предотвратить предупреждение?

Редактировать2:Некоторые дополнительные случаи (следующие из приведенных выше случаев):

a += A;         /* warning converting from int to char */
a++;            /* ok */
a += (char)1;   /* warning converting from int to char */

Кроме того, то, о чем я спрашиваю, является субъективным, и мне хотелось бы услышать, как другие люди справляются с предупреждениями о конверсиях в подобных случаях, если учесть, что некоторые разработчики выступают за удаление все предупреждения.

ЯЭ:

Одним из возможных решений является просто использовать ints вместо charверно?На самом деле, он не только требует больше памяти, но и медленнее, как это демонстрирует следующий код.Математические выражения нужны только для того, чтобы получать предупреждения при построении с помощью -Wconversion.Я предположил версию, используя char переменные будут работать медленнее, чем при использовании intЭто из-за преобразований, но в моей (64-битной двухъядерной системе II) система int версия медленнее.

#include <stdio.h>

#ifdef USE_INT
typedef int var;
#else
typedef char var;
#endif

int main()
{
    var start = 10;
    var end = 100;
    var n = 5;
    int b = 100000000;
    while (b > 0) {
        n = (start - 5) + (n - (n % 3 ? 1 : 3));
        if (n >= end) {
            n -= (end + 7);
            n += start + 2;
        }
        b--;
    }
    return 0;
}

Проходить -DUSE_INT в gcc для создания int-версии приведенного выше фрагмента.

Это было полезно?

Решение

Когда ты говоришь /* int */ Вы имеете в виду, что он предупреждает вас об этом?Я вообще не вижу никаких предупреждений в этом коде с gcc 4.0.1 или 4.2.1 с -Wconversion.Компилятор преобразует эти перечисления в константы.Поскольку все известно во время компиляции, нет смысла генерировать предупреждение.Компилятор может оптимизировать всю неопределенность (это Intel с версией 4.2.1):

    movb    $45, -1(%rbp)    # a = 45
    movzbl  -1(%rbp), %eax
    incl    %eax
    movb    %al, -2(%rbp)    # b = 45 + 1
    movb    $44, -3(%rbp)    # c = 44 (the math is done at compile time)
    movzbl  -1(%rbp), %eax   
    cmpb    -2(%rbp), %al
    jle     L2               
    movzbl  -2(%rbp), %eax
    movb    %al, -17(%rbp)
    jmp     L4
L2: 
    movzbl  -3(%rbp), %eax
    movb    %al, -17(%rbp)
L4:
    movzbl  -17(%rbp), %eax
    movb    %al, -4(%rbp)    # d = (a > b ? b : c)

Это без включения оптимизации.Благодаря оптимизации он рассчитает b и d для вас во время компиляции и жестко запрограммирует их окончательные значения (если они действительно нужны ему для чего-либо).Дело в том, что gcc уже понял, что здесь не может быть проблем, потому что все возможные значения укладываются в char.

РЕДАКТИРОВАТЬ:Позвольте мне несколько исправить это.Возможна ошибка в назначении b, и компилятор никогда его не поймает, даже если это точно.Например, если b=a+250;, то это обязательно переполнится b но gcc не выдаст предупреждение.Это потому, что задание a является законным, a это char, и ваша проблема (а не компилятора) — убедиться, что математические вычисления не переполняются во время выполнения.

Другие советы

Возможно, компилятор уже видит, что все значения умещаются в символ, поэтому его не беспокоит предупреждение.Я ожидаю, что enum нужно решить в самом начале компиляции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top