2009-11-13 3 views
5

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

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

#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 к полукокса. Не следует ли предупреждать о возможной потере данных? Компилятор Microsoft (который я настроил очень строгий) выдает предупреждение, а GCC - нет.

Вот варианты GCC я использую:

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

Я пропускаю некоторые опции GCC, чтобы время компиляции проверки еще строже?

ответ

9

Вы ищете

-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 изменилось с version 4.3 - старое предупреждение о прототипах вынуждающих преобразование типа теперь доступен в качестве -Wtraditional-conversion.

+1

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html Эта ссылка покажет вам, что _is_ включено в Wall and Wextra. Почему wconverersion не является полной загадкой/ошибкой. – Pod

+1

Мое мнение состоит в том, что эти предупреждения являются болью в задней части гораздо чаще, чем они что-то ловят, и мое решение о политических решениях gcc состоит в том, что они склонны так думать. Было бы неплохо иметь один вариант -W, который означал бы «проверить все, независимо от того, насколько раздражает», конечно. –

+1

не работает для меня. используя «gcc -g -Werror -ansi -pedantic -Wall -Wextra -Wconversion foo.c» с приведенным выше кодом в файле foo.c не дает никаких предупреждений с gcc 4.1.2 – Glen

2

-Wall doesn't quite mean -Wall, -Wextra уже находится под огнем за то, что он немного чересчур педантичен.

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

+0

, если вам не нравятся предупреждения о сравнении подписей, отключите их; Кроме того, строгие предупреждения могут быть проблемой для устаревших кодовых баз, но если вы начинаете с нуля, на самом деле не так сложно сделать ваш код без предупреждения - я думаю, что некоторые люди просто ленивы;) – Christoph

1

В C, присвоение int char является законным.

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

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

0

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

2

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

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

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

2

Я не получил предупреждение/ошибку с -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 

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

+0

Имейте в виду, что для вариационного как printf(), char будет передан как int и что% d является спецификатором правильного формата, чтобы получить числовое значение. A% c выведет значение в качестве символа, разница между «65» и «A». –

+0

Вправо (хотя, актер сделает его явным и, таким образом, удалит предупреждение). Моя точка зрения была больше связана с тем, что несколько точек зрения важны при попытке закрыть код ошибки/ошибки. – ezpz