в C: void * тип? - PullRequest
       25

в C: void * тип?

0 голосов
/ 20 марта 2019

В некоторых обсуждениях утверждается, что void * является "указателем на объект void", но в стандарте C 6.5.3.4, пункт 2, написано: «Оператор sizeof возвращает размер (в байтах) .... Размер определяется по типу операнда». Поэтому утверждается, что функция sizeof () получает тип в качестве аргумента.

То есть компилятор считает void * типом? или использование * это только для семантической интерпретации?

Ответы [ 2 ]

5 голосов
/ 20 марта 2019

A void * - допустимый тип с известным размером.На это указывает либо какой-либо объект, тип которого неизвестен, либо действительная нетипизированная память (т. Е. Память, возвращенная из malloc).Таким образом, sizeof(void *) является допустимым выражением.

В пункте 1 пункта 6.5.3.4 говорится:

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

Поскольку void * не является неполным типом, sizeof(void *) допустим.Однако, поскольку тип void является неполным, sizeof(void) недопустим.

Обращаясь к вашему комментарию о void **, это также допустимый тип, который указывает на объект типа void *.

Некоторые компиляторы, такие как GCC, реализуют расширение, где void имеет размер 1, поэтому sizeof(void) == 1 и арифметика указателей на void * функционируют аналогично арифметике на char *.Это, однако, идет вразрез со стандартом.

4 голосов
/ 20 марта 2019

void * действительно тип. Так же как и void.

void - это неполный тип, который не может быть завершен - он представляет пустой набор значений. Поскольку это неполный тип, он не может быть операндом оператора sizeof. Следовательно, void (логически) не имеет размера, и вы не можете создать объект типа void.

void * - это тип указателя и, как таковой, это полный тип. Он действует как «универсальный» тип указателя и может быть преобразован в другие типы указателей без приведения. Вы не можете разыменовать void *, так как результат будет иметь тип void, и у вас не может быть объекта типа void - вы должны сначала преобразовать его в указатель на полный тип.

void * имеет тот же размер и представление, что и char *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...