Как отключить ошибочные сообщения с плавающей точкой / длинные ошибки от GCC - PullRequest
2 голосов
/ 15 апреля 2009

Я недавно вносил изменения в нашу кодовую базу с плавающей на длинную для некоторых переменных и обнаружил, что в областях, которые, как я знал, все еще неточности, не было сообщений об ошибках, генерируемых компилятором. Это привело меня к добавлению -Wconversion к флагам компилятора. Но, к сожалению, это приводит к ложным сообщениям об ошибках. В приведенном ниже фрагменте я получаю ошибки, как отмечено. Что я могу сделать, чтобы подавить это сообщение в каждом конкретном случае, или уговорить gcc быть более умным по этому поводу? Флаг -Wconversion генерирует тысячи предупреждений в нашей базе кода. Я собираюсь изучить их все? Хмм.

#include <stdio.h>
void
takes_a_float  ( float some_num ) {
    printf("float Hello %f\n", some_num );
}
int
main (int argc, char **argv)  {
    float my_boat = 1.0f;
    takes_a_float (  my_boat );
    exit (0);
}

gcc -Wconversion foo.c
foo.c: In function `main':
foo.c:13: warning: passing arg 1 of `takes_a_float' as `float' rather than `double' due to prototype

 $ gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr   /share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)

EDIT

Как указал Джон Милликин, флаг -Wconversion работает «как задумано». (Я думал, что речь идет о преобразовании типов, но оказывается, что речь идет о преобразовании действительно старых программ в стиле C в стандарт ISO C. Черт. Чтение предупреждения gcc Страница документации для моей версии gcc не дает мне надежду, но в любом случае мне действительно нужен какой-то другой флаг предупреждения, который будет правильно предупреждать в следующем коде и не давать ложных предупреждений.

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


void
takes_a_long  ( long sad_story ) {
    printf("Long %lu\n", sad_story );
}

void
takes_a_float  ( float my_boat ) {
    printf("Float  %f\n", my_boat );
}

int
main (int argc, char **argv)  {

    float   my_boat     = 1.0f;
    long    sad_story   = 1.0L;

    // No warnings wanted
    takes_a_float (my_boat);
    takes_a_long (sad_story);

    // Warnings required
    takes_a_long  (my_boat);
    takes_a_float (sad_story);

    exit (0);
}

Редактировать 2

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

Ответы [ 4 ]

3 голосов
/ 15 апреля 2009

Из справочной страницы (также в http://lists.apple.com/archives/xcode-users/2008/Jul/msg00720.html):

-Wconversion

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

Итак, предупреждение выполняется точно так, как задокументировано. Если вы хотите специально проверить некоторые преобразования, попробуйте включить -Wconversion за один прогон, записать его в файл и выполнить поиск long -> float преобразований.


Эта опция, очевидно, предназначена для использования при переносе традиционного C на ISO / ANSI C.

2 голосов
/ 15 апреля 2009

Я полагаю, что вы, скорее всего, ищете флаг -Wall, который вы, возможно, захотите объединить с -std=XX, где XX - один из (c89 | gnu89 | c99 | gnu99 | ...) и / или, возможно, -pedantic, что еще более раздражает педантично (или даже * сдерживает в зависимости от вашего настроения:)

Кстати, вы забыли включить stdlib.h (для exit ()).


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

void takes_a_float ( float some_num ) {
    printf("float Hello %f\n", some_num );
}

int main (int argc, char **argv)  {
   float my_boat = 1.0;
   takes_a_float (  my_boat );
   exit( 0 );
}

и вывод моей консоли:


mctaylor@tigger:stackoverflow$ gcc -Wall -pedantic long_float.c -o long_float
mctaylor@tigger:stackoverflow$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
...
gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12) 

Использование -Wall -pedantic заставляет вас писать чистый, явный код и может помочь вам обнаружить множество потенциальных глупых ошибок. Удачи.

Интересно, могут ли "отсутствующие предупреждения" быть вызваны правилами продвижения типа C. (См. K & R Язык программирования C, 2-е изд, раздел 2.7 - Преобразование типов ). Просто пища для размышлений.

Надеюсь, это поможет.

ИЗМЕНЕНО для добавления дополнительных материалов (далее):

Другой вариант или подход: splint (Secure Programming Lint) или Gimple Software * PC-lint / FlexLint , которые lint реализуют статический анализ исходного кода C, который помечает подозрительные и непереносимые конструкции.


mctaylor@tigger:stackoverflow$ splint sad_story.c 
Splint 3.1.2 --- 07 May 2008

sad_story.c: (in function takes_a_long)
sad_story.c:5:26: Format argument 1 to printf (%lu) expects unsigned long int
                     gets long int: sad_story
  To ignore signs in type comparisons use +ignoresigns
   sad_story.c:5:20: Corresponding format code
sad_story.c: (in function main)
sad_story.c:21:18: Function takes_a_long expects arg 1 to be long int gets
                      float: my_boat
  To allow all numeric types to match, use +relaxtypes.
sad_story.c:22:19: Function takes_a_float expects arg 1 to be float gets long
                      int: sad_story
sad_story.c:12:15: Parameter argc not used
  A function parameter is not used in the body of the function. If the argument
  is needed for type compatibility or future plans, use /*@unused@*/ in the
  argument declaration. (Use -paramuse to inhibit warning)
sad_story.c:12:28: Parameter argv not used
sad_story.c:4:6: Function exported but not used outside sad_story: takes_a_long
  A declaration is exported, but not used outside this module. Declaration can
  use static qualifier. (Use -exportlocal to inhibit warning)
   sad_story.c:6:1: Definition of takes_a_long
sad_story.c:8:6: Function exported but not used outside sad_story:
                    takes_a_float
   sad_story.c:10:1: Definition of takes_a_float

Finished checking --- 7 code warnings

Вы также можете попробовать пример из FlexLint на онлайн-тестировании Gimpel , который является более чистым и красивым.

2 голосов
/ 15 апреля 2009

Просто предположение на информационных страницах, вы пробовали -Wno-traditional-conversion?

Редактировать: Я проверил, и это работает, но, к сожалению, это работает только с gcc 4.3 и новее. Из справочной страницы gcc 4.1 кажется, что наблюдаемое вами поведение - это то, что -Wconversion должен был делать в более старых версиях, и оно не предупреждает о нормальном double -> float преобразовании.

0 голосов
/ 15 апреля 2009

Я не получаю это предупреждение, наверное, потому что я использую более свежую версию GCC (4.3.3).

...