неявное описание функции - PullRequest
0 голосов
/ 27 июня 2011

GCC обычно выдает это предупреждение, когда правильный заголовочный файл не включен. Эта ссылка -> www.network-theory.co.uk / docs / gccintro / gccintro_19.html говорит о том, что поскольку объявление функции является неявным (а не явно объявленным через заголовок), неправильные типы аргументов могут фактически передаваться в функцию, давая неверные результаты. Я не понимаю этого. Означает ли это, что компилятор генерирует код, который помещает что-то, размером с слово машины, в стек для потребляемого вызывающего и надеется на лучшее?

Деталь приветствуется.

Ответы [ 2 ]

3 голосов
/ 27 июня 2011

Если у компилятора нет конкретной информации о том, как должен передаваться аргумент, например, когда нет прототипа или для аргументов, которые передаются, когда у прототипа есть многоточие ('...'), компилятор следует определеннымправила передачи аргументов.Эти правила в основном следуют тому, что происходило в предстандартном (или K & R) C - до того, как были использованы прототипы.Перефразировано из C99 6.5.2.2/6 «Вызовы функций»:

* the integer promotions are applied
* if the argument has float type it's promoted to double

После применения этих продвижений аргументов по умолчанию аргумент просто копируется туда, куда компилятор обычно копирует аргументы (как правило, в стек).Таким образом, аргумент struct будет скопирован в стек.

Если фактическая реализация функции не соответствует тому, как компилятор создает параметры, то вы получите неопределенное поведение (за исключением несоответствия со знаком или без знака, если значение можетбыть представленными или указатели на char и указатели на void могут быть смешаны / сопоставлены).

Также в C90, если функция неявно объявлена ​​(что C99 не разрешает, хотя она разрешает функции без прототипов),возвращаемое значение по умолчанию равно int.Еще раз, фактическая функция возвращает что-то еще, неопределенные результаты поведения.

3 голосов
/ 27 июня 2011

В классическом K & R C это почти то, что произошло;существовали приведения по умолчанию (например, все, что меньше (int), было переведено в (int)), и для обратной совместимости любая функция без прототипа по-прежнему вызывается таким образом, но, в общем, единственное указание, которое вы получили за неправильную передачуТип был странным результатом или, возможно, дамп ядра.Вот где вы попадаете в беду: когда у функции есть прототип, передается точное (не принудительное / повышенное) значение.Таким образом, если вы передаете (char), если в области видимости есть прототип, то вызывающая сторона выдвигает один байт, в противном случае 4 байта (на большинстве современных платформ).Если вызывающий и вызываемый абоненты не согласны с этим, произойдут плохие вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...