Я читаю книгу ( Программирование с помощью POSIX Threads by Butenhof, 1997), в которой используется C, и наткнулся на следующую строку:
(void)free(data);
Здесь data
просто указатель на выделенную структуру,
data = malloc(sizeof(my_struct_t));
Почему результат free
будет приведен к void
?
Из моего понимания C это, кажется, не имеет смысла по двум причинам:
- Бесплатная функция уже возвращает
void
- Код не использует возвращаемое значение (он даже не присваивается переменной)
Книга была написана в 1997 году. Это что-то вроде наследства?
Автор упоминает, что примеры были запущены на Digital Unix 4.0d, но я до сих пор не могу представить себе причину когда-либо приводить результат функции, если вы не собираетесь использовать этот результат.
free()
как к странности в книге, которую вам не нужно подражать. Когда-то давно это было уместно, но уже не актуально.Ответы:
Если мы говорим о стандартной
free
функции, то ее прототипПоэтому актерский состав совершенно бесполезен.
Теперь немного спекуляций.
Автор, возможно, забыл включить
stdlib.h
заголовок, объявляющий этот прототип, поэтому компилятор принимает тип возвращаемого значения какint
. Теперь во время статического анализа этого кода компилятор предупреждал о неиспользованном возвращаемом значении того, что он считает неработающимvoid
. Такие предупреждения обычно замалчиваются путем добавления актеров кvoid
.источник
free
того, который он имеет на самом деле, в результате чего вызов имеет неопределенное поведение (предположим, семантика C90, когда вызов необъявленной функции по своей природе не показывает UB во всех случаях). На практике вполне вероятно, что это приведет к добросовестному поведению в некоторых системах. Правильное решение - предоставить правильное объявление для функции.Это было бы наследством!
До того, как появился стандарт C,
free()
функция была бы (неявно) типаint
- потому что еще не было надежного типаvoid
для возврата. Не было возвращено значение.Когда код был впервые изменен для работы со стандартными компиляторами Си, он, вероятно, не включал
<stdlib.h>
(потому что он не существовал до стандарта). Старый код писалextern char *malloc();
(может быть безextern
) для функций распределения (аналогично дляcalloc()
иrealloc()
), и не нужно было объявлятьfree()
. И код затем приведёт возвращаемое значение к правильному типу - потому что это было необходимо по крайней мере в некоторых системах (включая ту, на которой я изучал C).Некоторое время спустя
(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 МБ до подкачки и т. Д.)источник
free()
на с. 177, который неявно возвращаетсяint
.void
был добавлен в некоторые системы (возможно, Unix System III) до выпуска стандарта, но это не было частью C, когда K & R 1st Edn был написан (1978). Функция, которая не возвращала значение, была объявлена без возвращаемого типа (что означало, что она возвращаласьint
), и до тех пор, пока вы не использовали значение, которое не было возвращено, проблем не было. Стандарт C90 должен был относиться к такому коду как к допустимому - он потерпел бы неудачу, как если бы он не был стандартным. Но C99 удалилint
правила «неявного » и «неявного объявления функции». Не весь код в мире догнал.(void)
бросок дляprintf()
??Этот актерский состав не нужен. Это, вероятно, не было бы в то время, когда C был стандартизирован в форме C89.
Если бы это было так, это было бы связано с неявным объявлением . Обычно это означало, что человек, пишущий код, забыл
#include <stdlib.h>
и использовался статический анализатор. Это не лучший обходной путь, и гораздо лучшая идея была бы#include <stdlib.h>
вместо этого. Вот некоторая формулировка из C89 о неявном объявлении:Но это странно, потому что они не приводят
malloc
ни к какому результату ,malloc
иfree
находятся в одном заголовочном файле.Также возможно, что это просто ошибка или какой-то способ сообщить читателю, что
free
результат не возвращается.источник
free
но не дляmalloc
.