真空的大小是多少?

这份声明会产生什么结果?

void *p = malloc(sizeof(void));

编辑: 问题的扩展。

如果 sizeof (void)在 GCC 编译器中生成1,那么就分配了1字节的内存,指针 p 指向该字节,p + + 会增加到0x2346吗?假设 p 是0x2345。我说的是 P 而不是 * p。

84638 次浏览

The type void has no size; that would be a compilation error. For the same reason you can't do something like:

void n;

EDIT. To my surprise, doing sizeof(void) actually does compile in GNU C:

$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out
1

However, in C++ it does not:

$ 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

In C, sizeof(void) == 1 in GCC, but this appears to depend on your compiler.

In C++, I get:

In function 'int main()':
Line 2: error: invalid application of 'sizeof' to a void type
compilation terminated due to -Wfatal-errors.

Although void may stand in place for a type, it cannot actually hold a value. Therefore, it has no size in memory. Getting the size of a void isn’t defined.

A void pointer is simply a language construct meaning a pointer to untyped memory.

sizeof() cannot be applied to incomplete types. And void is incomplete type that cannot be completed.

If you are using GCC and you are not using compilation flags that remove compiler specific extensions, then sizeof(void) is 1. GCC has a nonstandard extension that does that.

In general, void is a incomplete type, and you cannot use sizeof for incomplete types.

Taking the size of void is a GCC extension.

To the 2nd part of the question: Note that sizeof(void *)!= sizeof(void). On a 32-bit arch, sizeof(void *) is 4 bytes, so p++, would be set accordingly.The amount by which a pointer is incremented is dependent on the data it is pointing to. So, it will be increased by 1 byte.

while sizeof(void) perhaps makes no sense in itself, it is important when you're doing any pointer math.

eg.

 void *p;
while(...)
p++;

If sizeof(void) is considered 1 then this will work. If sizeof(void) is considered 0 then you hit an infinite loop.

Most C++ compilers choosed to raise a compile error when trying to get sizeof(void).

When compiling C, gcc is not conforming and chose to define sizeof(void) as 1. It may look strange, but has a rationale. When you do pointer arithmetic adding or removing one unit means adding or removing the object pointed to size. Thus defining sizeof(void) as 1 helps defining void* as a pointer to byte (untyped memory address). Otherwise you would have surprising behaviors using pointer arithmetic like p+1 == p when p is void*. Such pointer arithmetic on void pointers is not allowed in c++ but works fine with when compiling C with gcc.

The standard recommended way would be to use char* for that kind of purpose (pointer to byte).

Another similar difference between C and C++ when using sizeof occurs when you defined an empty struct like:

struct Empty {
} empty;

Using gcc as my C compiler sizeof(empty) returns 0. Using g++ the same code will return 1.

I'm not sure what states both C and C++ standards on this point, but I believe defining the size of some empty structs/objects helps with reference management to avoid that two references to differing consecutive objects, the first one being empty, get the same address. If reference are implemented using hidden pointers as it is often done, ensuring different address will help comparing them.

But this is merely avoiding a surprising behavior (corner case comparison of references) by introduction another one (empty objects, even PODs consume at least 1 byte memory).

void has no size. In both C and C++, the expression sizeof (void) is invalid.

In C, quoting N1570 6.5.3.4 paragraph 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.

(N1570 is a draft of the 2011 ISO C standard.)

void is an incomplete type. This paragraph is a constraint, meaning that any conforming C compiler must diagnose any violation of it. (The diagnostic message may be a non-fatal warning.)

The C++ 11 standard has very similar wording. Both editions were published after this question was asked, but the rules go back to the 1989 ANSI C standard and the earliest C++ standards. In fact, the rule that void is an incomplete type to which sizeof may not be applied goes back exactly as far as the introduction of void into the language.

gcc has an extension that treats sizeof (void) as 1. gcc is not a conforming C compiler by default, so in its default mode it doesn't warn about sizeof (void). Extensions like this are permitted even for fully conforming C compilers, but the diagnostic is still required.