Страницы

Поиск по вопросам

среда, 10 октября 2018 г.

sizeof(void) == 1?

Случайно опечатался и получил от оператора sizeof - 1.
#include "stdio.h" int main(void) { printf("%d",sizeof(void)); /// 1 return 0; }
Может мне кто-нибудь объяснить в чем тут дело?


Ответ

Согласно стандарту C (раздел 6.2.5 Types)
19 The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
и (6.5.3.4 The sizeof and alignof operators)
1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. The alignof operator shall not be applied to a function type or an incomplete type.
Однако некоторые компиляторы имеют собственные расширения языка, которые все же определяют выражение sizeof( void ), как имеющее значение 1.
Дело в том, что тип void не сразу же появился в языке программирования C. Из Rationale for International Standard— Programming Languages— C раздел 6.4.1 Keywords
Several keywords were added in C89: const, enum, signed, void and volatile.
Ранее его роль играл тип char. Например, если вы хотели скопировать один объект в другой с использованием стандартной функции memmove, то соответствующая запись могла выглядеть как
memmove( ( char *)obj1, ( char * )obj2, n );
Подобного вида запись еще можно встретить в старых программах.
В настоящее время функция memmove имеет следующее объявление
void *memmove(void *s1, const void *s2, size_t n);
и, как известно, любой указатель может быть приведен неявно к типу void *, а потому никакого явного приведения типов для вызова этой функции не требуется. Вы можете написать просто
memmove( obj1, obj2, n );
при использовании этой функции с указателями любого типа.
И лишь со временем я C был введен тип void.
Из Rationale for International Standard— Programming Languages— C раздел 6.5.4 Cast operators
The new type void*, which has the same representation as char*, is therefore preferable for arbitrary pointers
По аналогии с типом char, так как указатели void * имеют такое же представление, как и указатели char *, в некоторых компиляторах сделали размер void равным 1, так как sizeof( *(char *)NULL ) равно 1. Однако, как следует из стандарта C этот тип не имеет размера, так как он всегда является неполным типом, а потому такая конструкция, как sizeof( void ), является некорректной, и компилтор должен выдавать сообщения об ошибке, если его собственные расширения отключены при компиляции программы.

Комментариев нет:

Отправить комментарий