Законно ли объявление неявной функции в C89?

Рассмотрим эту программу C:

int main()
{
    puts("Hello world!");
    return 0;
}

Это компилируется и работает нормально и, насколько я понимаю, является законным C89. Однако я не уверен на 100% в этом. Компиляция в режиме C99 с clang сообщает мне, что implicit declaration of function 'puts' is invalid in C99 (что заставляет меня думать, что стандарт C должен был измениться в C99, чтобы сделать объявление неявной функции незаконным, что я и пытаюсь подтвердить).

Законно ли объявление неявной функции в C89? (даже если это плохая идея (если только вы не участвуете в запутанном коде C))


person Cornstalks    schedule 07.07.2013    source источник
comment
Этот ответ на аналогичный вопрос может вам немного помочь.   -  person Frxstrem    schedule 07.07.2013


Ответы (2)


Законно ли объявление неявной функции в C89?

да. Из раздела 3.3.2.2:

Если выражение, которое предшествует списку аргументов в скобках в вызове функции, состоит только из идентификатора, и если для этого идентификатора не видно объявления, идентификатор объявляется неявно точно так, как если бы в самом внутреннем блоке, содержащем вызов функции, объявление

    extern int  identifier();

появился.

person Oliver Charlesworth    schedule 07.07.2013
comment
В этом конкретном случае у него есть четко определенное поведение только потому, что puts возвращает результаты int. Для функции, отличной от int, поведение будет неопределенным. И, конечно, лучше просто добавить #include <stdio.h> в любом случае. - person Keith Thompson; 07.07.2013
comment
Кроме того, использование printf() вызвало бы неопределенное поведение, поскольку функции списка переменных аргументов, такие как printf(), должны быть соответствующим образом объявлены даже в C89. Вызывать их без прототипа в области видимости — плохая идея. - person Jonathan Leffler; 07.07.2013

Неявное объявление функции допустимо в C89, но удалено в C99. Это может быть подтверждено стандартом C11 (ISO/IEC 9899:201x).

В разделе C11 Forward перечислены все основные изменения в третьем издании (т. е. C11) и втором издании (т. е. C99), одно из которых:

Основные изменения во втором издании включали:

...

— удалить неявное объявление функции

Также в Обоснование международных стандартных языков программирования C §6.5.2.2 Вызовы функций

Новая возможность C99: в C99 удалено правило неявного объявления функций. В результате гарантируется создание диагностики, которая выявит дополнительную категорию ошибок программирования. После выдачи диагностики реализация может принять неявное объявление и продолжить трансляцию, чтобы поддержать существующие программы, которые использовали эту функцию.

person Yu Hao    schedule 11.07.2013