2016-07-22 2 views
2

Это не вопрос о том, как разрешить предупреждения о неявной декларации функций, которые появляются в программах на C, которые уже были answered.Почему «неявное объявление функции» является просто предупреждением?

Я понимаю, что это предупреждение о компиляторе, что мне интересно, почему это предупреждение, а не ошибка? Если компилятор не видит эту функцию, что происходит, когда функция вызывается во время выполнения? Ли линкеры в конечном итоге решить эту проблему? Или мы должны предположить, что поведение вызова функции, вызвавшей такое предупреждение, неизвестно?

+0

Вы должны предположить, что функция может принимать любое число или тип аргументов и возвращать 'int'. По крайней мере, это то, что делает компилятор. Это может быть удалено в будущих версиях спецификации. – user3386109

+1

Неявное правило 'int' больше не соответствует стандарту ... но может по-прежнему работать как расширение. Я не думаю, что в текущем стандарте есть что-то, что говорит, что компилятор * не может * предположить возврат 'int', его больше не требуется (и он должен выдать диагностику). – Dmitri

ответ

1

why is this a warning rather than an error?

Поскольку существует много устаревшего кода, то оно написано таким образом. Ошибка компилятора нарушит его.

If the compiler cannot see the function, what happens when the function is called at runtime? Does the linker ultimately resolve this issue?

Давайте посмотрим пример:

int main() 
{ 
    foo(); 
    return 0; 
} 

При работе компилятор генерирует свою собственную подпись функции, как int foo(...) и будет использовать его. Кстати, это может привести к очень любопытным ошибкам. Таким образом, объектный файл будет содержать вызов этой функции, и это нормально. Когда вы попытаетесь связать его, вы получите сообщение об ошибке: undefined reference to foo. Но если у вас есть другой модуль с определением foo, компоновщик найдет его по имени и свяжет его.

Or are we to assume that the behaviour of calling a function that produced such warning is unknown?

Как я уже сказал, это может привести к некоторым странным ошибкам. Представьте, что у вас есть код int i = foo() и foo без подписи. А в другом модуле у вас есть следующее: int * foo(){...}. При создании приложения в режиме с 64 битами вы ставите в i всего 32 бит 64-разрядного указателя. Таким образом, вы можете сказать, что поведение вашей программы может быть неизвестно.

-1

Стандартные места очень мало требований по реализации в отношении диагностики:

5.1.1.3 Diagnostics

1     A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances. 9)
9) The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.
+0

Этот ответ также объясняет, почему компиляторы генерируют предупреждения (а не ошибки) для ссылок на неопределенные глобальные переменные ... хотя они этого не делают. – immibis

0

Из-за вредных традиций, перенесенных господствующими компиляторов, в том числе тот, который вы используете. К счастью, у них обычно есть варианты сделать ошибку, например -Werror=implicit-function-declaration для gcc и совместимых компиляторов.