2015-09-04 1 views
3

Если я использую printf, scanf, puts или какую-либо другую функцию в C (не C++) и не писать строку include, может ли она рассматриваться как неопределенное или неопределенное поведение?Правильно ли удалить #include <stdio.h> в C?

Как я помню, C не требовал декларации porotope вообще, но было рекомендовано, чтобы они разрешали компилятору делать приведения типов при вызове. И прототипы для printf и другие такие функции не требуются, не уверены в пользовательских функциях.

PS: Этот вопрос относится к обсуждению в комментариях https://codegolf.stackexchange.com/a/55989/32091.

+0

Как вы можете скомпилировать код с этими функциями без включения? – LPs

+3

«C вообще не требует декларации поротопа» - это антикварный/средневековый C. С 1989 года требуются декларации (и вызов вариационной функции, если она не объявлена ​​как вариационная, является, в частности, UB). Но почему вы хотите сделать это все равно? –

+0

@LPs, easy: http://codepad.org/m4DB2Ndd - даже никаких предупреждений от gcc. – Qwertiy

ответ

2

Правильно ли удалить #include в C?

Нет, это неправильно. Всегда включайте его, если вы используете функцию stdio.h, такую ​​как printf.

C удаляет неявные декларации (с C99), и требуются включения. Единственная альтернатива - иметь видимое прототипированное объявление для printf.

Более того, даже если C имеет неявные декларации, неявные объявления не подходят для переменных функций аргументов; поэтому в C89 не добавление stdio.h включает и не имеет видимого прототипа (для примера printf) - это неопределенное поведение.

+0

Когда он был удален? – Qwertiy

+0

@Qwertiy см. Править – ouah

+0

@ouah: В этом случае, что такое пункт 7.1.4 - 2? – dhein

2

Для профессиональной разработки, нет.

Для codegolfing это нормально.

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

+0

Вопрос был не в профессиональном развитии - в этом случае я согласен с вами. Но вы абсолютно уверены, что функции от stdio не являются особым случаем в соответствии со стандартом? – Qwertiy

+0

@ Qwertiy Я не закрываю, но я вижу, что это очень маловероятно, потому что это языковая вещь, а не стандартная библиотека. – peterh

+0

На лету я бы предположил, что, поскольку стандарт только говорит о том, что окружающая среда должна обеспечивать эти функции, но система и компилятор могут быть рассмотрены как окружающая среда этой фразировкой, поэтому оба предоставляют ее, но ОС имеет более высокий приоритет. (но если вы посмотрите, то есть установочный каталог gcc, вы найдете в нем собственные реализации в виде файлов заголовков, которые для этого случая, но он может или не может предупредить об этом, поскольку он также может считаться средой, а также стандартными состояниями его функциональность должна быть такой: .... «Но -> это просто предположение о лету. – dhein

0

Технически вы можете пропустить #include во многих случаях. Но для некоторых функций компилятор не может генерировать правильный вызов функции без прототипа. Например. если параметр double и вы положили 0 - прототип будет преобразован и сохранен как значение double в стеке, и в противном случае будет int, что приведет к неправильным вычислениям.

+0

Я понимаю это. Но есть ли что-то явное в стандарте? – Qwertiy

+0

Первый стандарт C говорит, что без прототипа предполагается функция 'int func (void)' (if remem ber correcty). То есть нет прототипа, только когда параметров нет. – i486

1

Нет и Да

stdio.h имеет явную декларацию функций, которые вы хотите использовать, такие вещи запрещены, если это был C++ компилятор (г ++, например). Поскольку C++ требует явных объявления всех функций, но любое собственного C compiler создаст неявное декларации этих функций, компиляцию коды в файл объект, и при связывании со стандартной библиотекой, он будет найти определение этих функций что случайно будет соответствовать неявному объявлению, вероятно, gcc предоставит вам предупреждение.

Так что, если вы пишете программное обеспечение, которое должно быть удобным и удобным для чтения, это не вариант для его удаления, однако для быстрого прототипирования или проблем с кодом это может быть не так важно.

+0

«Возможно, это не так важно»? Попробуйте назвать что-то базовое, как 'malloc()' в среде LP64, не включая соответствующий заголовок .... –