Зачем приводить возвращаемое значение free к void? - PullRequest
82 голосов
/ 11 марта 2020

Я читаю книгу ( Программирование с использованием потоков POSIX от Butenhof, 1997), в которой используется C, и я наткнулся на следующую строку:

(void)free(data);

Здесь, data - это просто указатель на выделенную структуру,

data = malloc(sizeof(my_struct_t));

Почему результат преобразования free в void?

Из моего понимания C это кажется, не имеет смысла по двум причинам:

  • Свободная функция уже возвращает void
  • Код не использует возвращаемое значение (он даже не присваивается переменная)

Книга была написана в 1997 году. Это какая-то устаревшая вещь?

Автор упоминает, что примеры были выполнены на Digital Unix 4.0d, но я до сих пор не могу себе представить причину, чтобы когда-либо приводить результат функции, если вы не собираетесь использовать этот результат.

Ответы [ 3 ]

100 голосов
/ 11 марта 2020

Если мы говорим о стандартной функции free, то ее прототипом является

void free(void *ptr);

Поэтому приведение совершенно бесполезно.
Теперь некоторые предположения.

Автор может забыли включить заголовок stdlib.h, объявляющий этот прототип, поэтому компилятор принимает его тип возвращаемого значения int. Теперь во время статического анализа этого кода компилятор предупреждал о неиспользованном возвращаемом значении функции, которая, по его мнению, не является void. Такие предупреждения обычно заглушаются добавлением приведения к void.

74 голосов
/ 11 марта 2020

Это было бы унаследовано!

До появления стандарта C функция free() имела бы (неявно) тип int, поскольку еще не было надежного типа void чтобы вернуть. Не было возвращено значение.

Когда код был впервые изменен для работы со стандартными C компиляторами, он, вероятно, не включал <stdlib.h> (потому что он не существовал до стандарта). Старый код писал бы extern char *malloc(); (возможно, без extern) для функций распределения (аналогично для calloc() и realloc()), и ему не нужно было объявлять free(). И код затем приведёт возвращаемое значение к правильному типу - потому что это было необходимо по крайней мере в некоторых системах (включая ту, которую я изучил C on).

Некоторое время спустя преобразование (void) было добавлено, чтобы сообщить компилятору (или, более вероятно, lint), что «возвращаемое значение из free() намеренно игнорируется», чтобы избежать жалоб. Но было бы лучше добавить <stdlib.h> и позволить его объявлению extern void free(void *vp); сообщить lint или компилятору, что не было значения игнорировать.

JFTR: В середине 80-х годов Первоначально ICL Perq был ориентирован на слово, и адрес char * для ячейки памяти сильно отличался от «указателя что-нибудь» в том же месте. Важно было как-то объявить char *malloc(); было важно преобразовать результат из него в любой другой тип указателя. Приведение фактически изменило число, используемое процессором. (Было также много радости, когда основная память в наших системах была обновлена ​​с 1 МБ до 2 МБ - поскольку ядро ​​использовало около 3/4 МБ, это означало, что пользовательские программы могли использовать 1 1/4 МБ до paging et c .)

11 голосов
/ 11 марта 2020

Этот бросок не нужен. Вероятно, в то время этого не было бы, поскольку C было стандартизировано в форме C89.

Если бы это было так, это произошло бы из-за неявного объявления 1004 *. Обычно это означало, что человек, пишущий код, забыл #include <stdlib.h> и использовался анализатор состояния c. Это не лучший обходной путь, и гораздо лучшая идея была бы просто вместо #include <stdlib.h>. Вот некоторая формулировка из C89 о неявном объявлении:

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

extern int identifier();

.

Но это странно, потому что они не приводят результат malloc либо * и 1017 * и free находятся в одном заголовочном файле.

Возможно также, что это просто ошибка или какой-то способ сообщить читателю, что free не возвращает результата.

...