Риск компиляции предупреждения

У меня есть в основном два вида предупреждения компиляции:

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 по умолчанию" и для совместимости поддерживается даже в последних компиляторах.

Другие вопросы по тегам