Риск компиляции предупреждения
У меня есть в основном два вида предупреждения компиляции:
1. неявное объявление функции
в a.c
, она имеет char *foo(char *ptr1, char *ptr2)
, в b.c
некоторые функции используют это foo
функция без какого-либо объявления, и я нашел, кажется, компилятор будет относиться к функции foo
возвращаемое значение как целое число, и даже я могу передать некоторые переменные меньше или больше, чем foo
объявление функции
2. перечислимый тип, смешанный с другим типом
Моя целевая микросхема - ARM11, кажется, что даже я не решаю эти два вида предупреждений о компиляции, моя программа может работать без проблем, но я считаю, что за этим должен быть некоторый риск. Кто-нибудь может дать мне хороший пример того, что эти два вида предупреждений компиляции могут вызвать некоторые неожиданные проблемы?
Между тем, если эти два предупреждения имеют потенциальный риск, почему c-компилятор допускает появление таких предупреждений, но не устанавливает их на ошибку напрямую? какая-нибудь история позади?
2 ответа
Неявное объявление. Например, у вас есть функция: float foo(float a)
, который не объявлен, когда вы называете это. Неявные правила создадут авто-объявление со следующей подписью: int foo(double)
(если передан аргумент float). Таким образом, значение, которое вы передаете, будет преобразовано в удвоенное, но foo
надеется float
, То же самое с возвратом - ожидается код вызова int
, но вернулся float
, Значения были бы полным беспорядком.
enum, смешанный с другим типом. Перечислимый тип имеет список значений, которые он может принимать. Если вы пытаетесь присвоить ему числовое значение, есть вероятность, что оно не является одним из перечисленных значений; если позже ваш код ожидает только указанный диапазон и предполагает, что больше ничего не может быть - он может работать неправильно.
Простой пример:
Файл: warn.c
#include <stdio.h>
double foo(double x)
{
return myid(x);
}
int
main (void)
{
double x = 1.0;
fprintf (stderr, "%lg == %lg\n", x, foo (x));
return 0;
}
Файл: foo.c
double
myid (double x)
{
return x;
}
Скомпилируйте и запустите:
$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out
1 == 0
Старый стандарт C (C90) имел это странное правило "int по умолчанию" и для совместимости поддерживается даже в последних компиляторах.