(Я впервые начал писать программы на C где-то примерно в 1993 году. Тогда времена были другими, компиляторы могли быть другими, но я вспоминаю, что когда кто-то пытается обратиться к функции C, которая не объявлена, он получает ошибку.Кроме того, если функция определена позже, возможно, в другом модуле перевода, и «подписи» не совпадают, то вы получите еще одну ошибку.)
В настоящее время я использую GCC 4.4.3.Я озадачен тем, почему GCC так прощает мне (намеренно в примере) несоответствующее (необязательное) объявление bar
и его определение в bar.c
, которое, очевидно, приведет к фатальной ошибке адресации - поскольку bar
хочетадрес и получает целое число, в конечном итоге он отменяет ссылку на это целое число как адрес.Строгий компилятор, или я так думаю, прервал бы меня с ошибкой.Я что-то пропустил?Моя командная строка сборки выглядит следующим образом:
cc -o foobar -g -Wall -std=c99 -fexec-charset=ISO-8859-1 -DDEBUG foo.c bar.c
С foo.c
:
int main()
{
int a;
bar(a);
return 0;
}
и bar.c
:
void bar(int * a)
{
*a = 1;
}
Я намеренно пропустил объявлениеbar
, а также намеренно передать ему целое число (может быть что угодно) вместо адреса, как того требует его фактическое определение.Суть для меня такова: поскольку $ (CC) не останавливает меня, я заканчиваю с ошибкой сегментации (x86, Ubuntu 10.04).Я знаю, что совместимый компилятор C (C99?) Неявно создал бы объявление int bar(void)
для bar
, если ничего не найдено, но в этом случае это явно не то, что я хочу вообще!Я хочу уберечь себя от ошибок, когда я делаю человеческую ошибку, не совмещая объявления и определения или вообще пропуская первые.
Я пытался вместо этого только компилировать - с помощью -c
переключателя компилятора - ноэто не имеет значения, поскольку оно все еще успешно с предупреждениями.Хотя компоновщик может раздражать, но я хочу, чтобы компилятор остановил меня до того, как это произойдет.
I на самом деле не хочет превращать мои предупреждения в ошибки, скажем -Werror
, потому что:
- Я мог бы указать неверный
float bar(double a);
в верхней части foo.c
, что полностью исключает предупреждение, но не меняет факт сбоя программы.Увы, программа, которая успешно компилируется без предупреждений (даже с переключателем -Wall
) и прекрасно аварийно завершает работу во время выполнения. - У меня есть и будут другие типы предупреждений, которые должны оставаться предупреждениями, а не препятствовать успешным сборкам.
- Это будет иметь дело с эффектом проблемы, а не с самой проблемой
- Это не только типы предупреждений, но и конкретные случаи.Я бы не хотел превращать конкретный код предупреждения в ошибку, потому что в некоторых случаях это было бы неприменимо.Это было бы слишком грубым решением, которое не учитывает специфику и контекст, в котором произошло предупреждение.