Каков размер пустоты?
что бы это заявление даст?
void * p = (void*) malloc(sizeof(void));
Edit: расширение к вопросу.
Если sizeof (void) дает 1 в компиляторе GCC, то выделяется 1 байт памяти и указатель p указывает на этот байт и будет ли P++ увеличен до 0x2346? Предположим, что p равно 0x2345. Я говорю о p, а не *p.
10 ответов:
тип
void
не имеет размера; это было бы ошибкой компиляции. По той же причине вы не можете сделать что-то вроде:void n;
правка. К моему удивлению, делаю
sizeof(void)
на самом деле тут компиляция в GNU C:$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out 1
однако, в C++ это не:
$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc++ -w - && ./a.out <stdin>: In function 'int main()': <stdin>:1: error: invalid application of 'sizeof' to a void type <stdin>:1: error: 'printf' was not declared in this scope
Если вы используете GCC и не используете флаги компиляции, которые удаляют определенные расширения компилятора, то
sizeof(void)
Это 1. GCC имеет нестандартное расширение что делает.В общем,
void
является неполным типом, и вы не можете использовать sizeof для неполных типов.
хотя
void
может стоять на месте, для вида, он не может вообще иметь значение. Поэтому он не имеет размера в памяти. Получение размераvoid
Не определен.A
void
указатель это просто языковая конструкция, означающая указатель на untyped память.
принимая размер пустоты является расширение GCC.
void
не имеет размера. Как в C, так и в C++ выражениеsizeof (void)
является недействительным.в C, цитирую N1570 6.5.3.4 пункт 1:
The
sizeof
оператор не должен применяться к выражению, которое имеет тип функции или неполный тип в скобках имя такой тип или выражение, которое обозначает элемент битового поля.(N1570-проект 2011 года Стандарт ISO C.)
void
является неполным типом. Этот абзац является ограничения, что означает, что любой соответствующий компилятор C должен диагностировать любое его нарушение. (Диагностическое сообщение может быть несмертельным предупреждением.)стандарт C++ 11 имеет очень похожую формулировку. Оба издания были опубликованы после того, как был задан этот вопрос, но правила восходят к стандарту ANSI C 1989 года и самым ранним стандартам C++. На самом деле, правило, что
void
неполный тип, к которомуsizeof
не может быть применен возвращается точно так же, как введениеvoid
на язык.gcc имеет расширение что относится к
sizeof (void)
как 1. gcc по умолчанию не является соответствующим компилятором C, поэтому в своем режиме по умолчанию он не предупреждает оsizeof (void)
. Такие расширения разрешены даже для полностью соответствующих компиляторов C, но диагностика по-прежнему требуется.
sizeof()
не может применяться к неполным типам. Иvoid
является неполным типом, который не может быть завершен.
В C,
sizeof(void) == 1
в GCC, но это, кажется, зависит от вашего компилятора.В C++, я получаю:
In function 'int main()': Line 2: error: invalid application of 'sizeof' to a void type compilation terminated due to -Wfatal-errors.
к 2-й части вопроса: обратите внимание, что sizeof (void *)!= sizeof (void). На 32-разрядной арке sizeof (void *) составляет 4 байта, поэтому p++ будет установлен соответствующим образом.Величина, на которую увеличивается указатель, зависит от данных, на которые он указывает. Таким образом, он будет увеличен на 1 байт.
хотя sizeof (void), возможно, не имеет смысла сам по себе, это важно, когда вы делаете любую математику указателя.
например.
void *p; while(...) p++;
Если sizeof (void) считается 1, то это будет работать. Если sizeof (void) считается 0, то вы попали в бесконечный цикл.
большинство компиляторов C++ выбрали, чтобы вызвать ошибку компиляции при попытке получить
sizeof(void)
.при компиляции C gcc не соответствует и решил определить
sizeof(void)
как 1. Это может показаться странным, но имеет свое обоснование. При выполнении арифметики указателя добавление или удаление одной единицы означает добавление или удаление объекта, указанного на размер. Таким образом, определениеsizeof(void)
как 1 помогает определениеvoid*
как указатель на байт (нетипизированный адреса памяти). В противном случае у вас будет удивительное поведение с помощью указателя арифметика вродеp+1 == p when
пvoid*
. Такая арифметика указателей на указатели void не допускается в c++, но отлично работает при компиляции C с помощью gcc.стандартный рекомендуемый способ будет использовать
char*
для такого рода целей (указатель на байт).другое аналогичное различие между C и C++ при использовании sizeof возникает, когда вы определили пустую структуру, например:
struct Empty { } empty;
использование gcc в качестве моего компилятора C
sizeof(empty)
возвращает 0. Используя g++ тот же код будет возвращение 1.Я не уверен, что утверждает стандарты C и C++ по этому вопросу, но я считаю, что определение размера некоторых пустых структур/объектов помогает при управлении ссылками избежать того, что две ссылки на разные последовательные объекты, первая из которых пуста, получают один и тот же адрес. Если ссылки реализуются с использованием скрытых указателей, как это часто делается, обеспечение другого адреса поможет сравнить их.
но это просто избегает удивительного поведения (угловой случай сравнения ссылок) путем введения другого (пустые объекты, даже стручки потребляют не менее 1 байта памяти).