空隙的大小是多少?

问题描述 投票:73回答:10

此语句将产生什么?

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

编辑:问题的扩展名。

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

c++ c language-lawyer sizeof
10个回答
52
投票

类型void没有大小;那将是一个编译错误。出于同样的原因,您不能执行以下操作:

void n;

编辑。令我惊讶的是,在sizeof(void)中实际上does在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

-1
投票

[大多数C ++编译器选择在尝试获取sizeof(void)时引发编译错误。

[编译C时,gcc不符合要求,因此选择将sizeof(void)定义为1。它可能看起来很奇怪,但是有其原理。当您进行指针算术运算时,添加或删除一个单位表示添加或删除指向大小的对象。因此,将sizeof(void)定义为1有助于将void*定义为指向字节(未类型化的存储器地址)的指针。否则,使用指针算法(例如p+1 == p when p为void*)会产生令人惊讶的行为。在C ++中不允许在void指针上使用这种指针算术,但在使用gcc编译C时可以很好地工作。

标准推荐的方法是将char*用于此类目的(指向字节的指针。)>

[使用sizeof时C和C ++之间的另一个类似区别是,当您定义一个空结构时,如:

struct Empty {
} empty;

使用gcc作为我的C编译器sizeof(empty)返回0。使用g ++,相同的代码将返回1。

我不确定在这一点上什么同时说明了C和C ++标准,但是我相信定义一些空结构/对象的大小有助于进行引用管理,从而避免两个对不同连续对象的引用,第一个为空,获得相同的地址。如果经常使用隐藏指针来实现引用,则确保不同的地址将有助于比较它们。

但是这只是通过引入另一个对象(空对象,甚至POD占用至少1个字节的内存)来避免令人惊讶的行为(对引用进行角落比较)。


39
投票

[如果您使用的是GCC,并且没有使用删除特定于编译器的扩展名的编译标志,则sizeof(void)为1。GCC具有执行该操作的nonstandard extension

通常,void是不完整的类型,不能将sizeof用于不完整的类型。


15
投票

尽管void可能代表一种类型,但实际上不能保存值。因此,它在内存中没有大小。未定义获取void的大小。

Avoidpointer只是一种语言构造,表示指向untyped内存的指针。


11
投票

void没有大小。在C和C ++中,表达式sizeof (void)都是无效的。

在C中,引用N1570 6.5.3.4第1段:

sizeof运算符不得应用于以下表达式函数类型为或不完整的类型,括号类型为这样的类型,或者指定位域成员的表达式。

((N1570是2011 ISO C标准的草案。)

void是不完整的类型。本段是constraint,表示任何符合标准的C编译器都必须诊断出任何对此的违反。 (诊断消息可能是非致命警告。)

C ++ 11标准的措辞非常相似。在问了这个问题之后,两个版本都发布了,但是规则可以追溯到1989年的ANSI C标准和最早的C ++标准。实际上,void是不适用sizeof的不完整类型的规则可以追溯到将void引入语言的程度。

gcc具有extension,它将sizeof (void)视为1。默认情况下,gcc不是兼容的C编译器,因此在其默认模式下,它不会警告sizeof (void)。即使完全兼容的C编译器也可以使用这种扩展,但是仍然需要诊断。


10
投票

以空隙的大小为GCC extension


5
投票

sizeof()无法应用于不完整的类型。并且void是无法完成的不完整类型。


3
投票

在C中,在GCC中为sizeof(void) == 1,但这似乎取决于您的编译器。

在C ++中,我得到:

在函数'int main()'中:第2行:错误:将'sizeof'无效应用到void类型由于-Wfatal-errors,编译终止。

0
投票

问题的第二部分:请注意,sizeof(void *)!= sizeof(void)。在32位的arch上,sizeof(void *)是4个字节,因此将相应地设置p ++。指针的增加量取决于它所指向的数据。因此,它将增加1个字节。


-1
投票

虽然sizeof(void)本身没有任何意义,但是在进行任何指针数学运算时,这一点很重要。

例如

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

如果将sizeof(void)视为1,那么它将起作用。如果将sizeof(void)视为0,那么您会遇到无限循环。

© www.soinside.com 2019 - 2024. All rights reserved.