GCC - не следует ли выдавать предупреждение при назначении int для символа? - PullRequest
7 голосов
/ 13 ноября 2009

Я недавно настроил среду MinGW + MSYS на своем ноутбуке, чтобы проверить, как обстоят дела с поддержкой Netbeans C / C ++. Кажется, все работает нормально, но во время тестирования я заметил разницу между GCC и компилятором Microsoft cl.exe.

Вот пример программы:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void) {
    int i_max = INT_MAX;
    char c_max = CHAR_MAX, c;

    c = i_max;
    printf("i_max: %d, c_max: %d, c: %d\n", i_max, c_max, c);
    return EXIT_SUCCESS;
}

Вывод:

i_max: 2147483647, c_max: 127, c: -1

Как вы можете видеть в коде выше, я присваиваю int для char. Разве это не должно выдавать предупреждение о возможной потере данных? Компилятор Microsoft (который я настроил очень строго) выдает предупреждение, а GCC - нет.

Вот параметры GCC, которые я использую:

-g -Werror -ansi -pedantic -Wall -Wextra

Мне не хватает какой-то опции GCC, чтобы сделать проверки времени компиляции еще строже?

Ответы [ 6 ]

9 голосов
/ 13 ноября 2009

Вы ищете

-Wconversion

Вы должны спросить разработчика gcc о конкретных причинах, по которым некоторые предупреждения не включены в -Wall или -Wextra.

В любом случае, я использую флаги:

-Wall -Wextra -Wmissing-prototypes -Wmissing-declarations -Wshadow
-Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Wnested-externs
-Winline -Wno-long-long -Wconversion -Wstrict-prototypes

Как уже отмечалось, поведение -Wconversion изменилось с версия 4.3 - старое предупреждение о прототипах, приводящих к преобразованию типов, теперь доступно как -Wtraditional-conversion.

2 голосов
/ 13 ноября 2009

Я также не получил предупреждение / ошибку с -Wconversion. Однако, если вы дадите пас с чем-то вроде splint, вы получите три предупреждения:

file.c: (in function main)
file.c:9:5: Assignment of int to char: c = i_max
  To make char and int types equivalent, use +charint.
file.c:10:52: Format argument 2 to printf (%d) expects int gets char: c_max
   file.c:10:32: Corresponding format code
file.c:10:59: Format argument 3 to printf (%d) expects int gets char: c
   file.c:10:39: Corresponding format code

Finished checking --- 3 code warnings

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

2 голосов
/ 13 ноября 2009

В вашем вопросе есть небольшой нюанс, который не сразу очевиден для меня в том виде, в котором он сформулирован.

Если вы считаете, что GCC (в частности, GCC) должен выдать предупреждение, то некоторые параметры компилятора могут помочь (см. Другие ответы).

Если вы думаете, любой компилятор должен выдать предупреждение здесь (и я, кажется, прочитал это чувство в вашем вопросе), то ... ну, "предупреждения" никоим образом не являются обязательными или даже -факто единый. Здесь нет «должен». Присвоение целочисленного значения с большим типом меньшему типу без явного приведения вполне допустимо в C. Переполнение при преобразовании приводит к поведению, определяемому реализацией (это даже не UB:))

2 голосов
/ 13 ноября 2009

-Wall не совсем означает -Wall , -Wextra уже под огнем из-за того, что он немного чрезмерно педантичен.

Как сказал Кристоф, вы ищете конверсию. Хорошо по-настоящему разобраться с тем, что на самом деле включают -Wall и -Wextra, и просто указать нужные флаги -W в файле make, особенно если рассматривать предупреждения как ошибки.

1 голос
/ 13 ноября 2009

В C присвоение int для символа допустимо.

Поскольку это законно (но, возможно, хитро), разные производители компиляторов делают разные вещи, когда сталкиваются с этим кодом.

Я полагаю, что MS просто педантичен, а ребята из GCC решили, что даже не стоит предупреждать.

0 голосов
/ 13 ноября 2009

Я думаю, что это подпадает под "Обычные арифметические преобразования" (6.3.1.8) или "правила целочисленного продвижения" (5.1.2.3 (?)), Но я не могу найти конкретный текст, который говорит о поведении, которое вы видение ожидается.

...