Почему функция strlen работает без #include <string.h>? - PullRequest
4 голосов
/ 27 апреля 2011

Быстрый вопрос:

strlen[char*] работает отлично, независимо от того, * I 1004 * или нет

Все, что я получаю от компилятора, - это предупреждение о неявном объявлении, но функционально оно работает как задумано.

Почему это?

Ответы [ 7 ]

6 голосов
/ 27 апреля 2011

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

4 голосов
/ 27 апреля 2011

Прототипы функций в C не обязательны . Они полезны для компилятора, так как он может выполнять проверку типов для типов, которые передаются в них. Если вы не включите string.h, для функции предполагается подпись по умолчанию, поэтому вы получаете предупреждение.

3 голосов
/ 27 апреля 2011

Если функция вызывается без прототипа в области видимости, компилятор сгенерирует код для вызова функции, которая принимает любые типы параметров и принимает целочисленный результат. Если параметры соответствуют тем, которые ожидает функция, и если функция возвращает свой результат способом, которым вызывающий код может обработать (*), все будет хорошо. Цель создания прототипа состоит в том, чтобы гарантировать, что аргументы преобразуются в ожидаемые типы, если это возможно, и что компиляция завершится неудачей, если их невозможно преобразовать. Например, если функция, не являющаяся прототипом, ожидает аргумент типа «long» и кто-то пытается передать «int», может произойти любое из следующего:

  1. Программа может аварийно завершить работу
  2. Вещи могут работать как положено
  3. Функция может выполняться так, как если бы ей было передано какое-то произвольное значение параметра
  4. Программа может продолжать работать, но с произвольными значениями, повреждающими любую или все программные переменные.
  5. Компьютер может стать причиной того, что демоны могут вылететь из носа программиста

Напротив, если бы функция была прототипирована, компилятор гарантированно сделает все необходимое для преобразования int в long до вызова функции.

Когда C был изначально задуман, прототипов не существовало, и программист отвечал за то, чтобы все аргументы передавались с ожидаемыми точными типами. На практике очень трудно убедиться, что все аргументы функции всегда являются точными правильными типами (например, при передаче значения пять в функцию, которая ожидает long, нужно записать его как «5L» или «(long) 5»). ). Реально говоря, нет (**) никаких причин полагаться на неявные типы аргументов, кроме как с помощью переменных функций.

(*) Любое из того, что может случиться с неправильными типами параметров, может происходить с неправильными типами возвращаемых значений, за исключением случаев, когда ожидается, что функция возвратит int, а фактическое возвращаемое значение функции поместится в int. результаты с большей вероятностью будут правильными, чем при использовании неверных типов параметров.

(**) Единственное исключение, о котором я могу подумать, было бы, если бы кто-то программировал для какого-то действительно старого оборудования, для которого компилятор с поддержкой прототипов был недоступен, или если он программировал для игры в гольф для кода или подобного соревнования. Последнее я считаю решением головоломок, а не программированием, и я не знаю ни одного аппаратного средства, которое люди могли бы использовать, для которого применимо первое условие.

1 голос
/ 27 апреля 2011

Обычно это потому, что другой заголовочный файл, который вы включили, также включает в себя string.h.Очевидно, что не стоит полагать, что вам не нужно включать что-то только потому, что это делает что-то другое, но это, скорее всего, ответственно за этот эффект.

1 голос
/ 27 апреля 2011

Потому что это объявление, то есть равное так называемому объявлению по умолчанию.Компилятор ожидает, что любая неизвестная функция возвратит int, и ожидает, что параметры будут переданы при первом использовании функции в коде.

0 голосов
/ 28 апреля 2011

Прототип функции находится во включаемых файлах.Поэтому, даже если вы не включите эти файлы, записывается фиксированный прототип int function_name();.Теперь код strlen() находится в файлах библиотеки, которые связаны во время выполнения, поэтому функция выдает правильный вывод (только если это единственная функция с фиксированным прототипом int function_name();).

0 голосов
/ 27 апреля 2011

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

...