C++ 空隙的大小是多少?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1666224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:49:59  来源:igfitidea点击:

What is the size of void?

c++clanguage-lawyersizeof

提问by Lakshmi

What would this statement yield?

这个语句会产生什么结果?

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


Edit: An extension to the question.

编辑:问题的扩展。

If sizeof(void) yields 1 in GCC compiler, then 1 byte of memory is allocated and the pointer p points to that byte and would p++ be incremented to 0x2346? Suppose p was 0x2345. I am talking about p and not *p.

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

采纳答案by reko_t

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

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

void n;

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

编辑。令我惊讶的是,这样做sizeof(void)实际上确实在 GNU C编译:

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

However, in C++ it does not:

但是,在 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

回答by hrnt

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 extensionthat does that.

如果您正在使用 GCC 并且您没有使用删除编译器特定扩展的编译标志,那么sizeof(void)是 1。GCC 有一个非标准扩展可以做到这一点。

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

一般来说,void是一个不完整的类型,你不能对不完整的类型使用 sizeof。

回答by Konrad Rudolph

Although voidmay stand in place for a type, it cannot actually hold a value. Therefore, it has no size in memory. Getting the size of a voidisn't defined.

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

A voidpointeris simply a language construct meaning a pointer to untypedmemory.

一个void指针是一个简单的语言建构意义的指针,无类型的内存。

回答by Keith Thompson

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

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

In C, quoting N15706.5.3.4 paragraph 1:

在 C 中,引用N15706.5.3.4 第 1 段:

The sizeofoperator 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.

sizeof操作者不得应用于具有功能类型的表达式或不完整的类型,这样的类型的括号名称,或者将指定的位字段构件的表达式。

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

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

voidis 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.)

void是不完整的类型。这一段是一个约束,这意味着任何符合标准的 C 编译器都必须诊断出任何违反它的行为。(诊断消息可能是非致命警告。)

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 voidis an incomplete type to which sizeofmay not be applied goes back exactly as far as the introduction of voidinto the language.

C++ 11 标准的措辞非常相似。两个版本都是在提出这个问题后发布的,但规则可以追溯到 1989 年的 ANSI C 标准和最早的 C++ 标准。事实上,void不完全类型的规则sizeof可能不会被应用void到语言中的引入。

gcc has an extensionthat 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.

gcc有一个扩展该治疗sizeof (void)为1的gcc是默认不相符的C编译器,因此在它的默认模式不发出警告sizeof (void)。即使对于完全符合标准的 C 编译器,也允许这样的扩展,但仍然需要诊断。

回答by pmg

Taking the size of void is a GCC extension.

取 void 的大小是GCC 扩展

回答by Aleksei Potov

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

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

回答by Greg Hewgill

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

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

In C++, I get:

在 C++ 中,我得到:

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

回答by Greg Hewgill

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.

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

回答by user906752

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

虽然 sizeof(void) 本身可能没有意义,但在您进行任何指针数学运算时它很重要。

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.

如果将 sizeof(void) 视为 1,那么这将起作用。如果 sizeof(void) 被认为是 0,那么你就会陷入无限循环。

回答by kriss

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

大多数 C++ 编译器在尝试获取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 whenp is void*. Such pointer arithmetic on void pointers is not allowed in c++ but works fine with when compiling C with gcc.

编译C的时候,gcc不符合,选择定义sizeof(void)为1。看起来很奇怪,但有道理。当您进行指针算术添加或删除一个单位时,意味着添加或删除指向大小的对象。因此定义sizeof(void)为 1 有助于定义void*为指向字节的指针(无类型内存地址)。否则,使用p+1 == p whenp is 之类的指针算术时,您会出现令人惊讶的行为void*。在 c++ 中不允许对 void 指针进行这种指针运算,但在使用 gcc 编译 C 时可以正常工作。

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

标准推荐的方法是char*用于那种目的(指向字节的指针)。

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

使用 sizeof 时,C 和 C++ 之间的另一个类似差异发生在您定义一个空结构时,例如:

struct Empty {
} empty;

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

使用 gcc 作为我的 C 编译器sizeof(empty)返回 0。使用 g++ 相同的代码将返回 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.

我不确定 C 和 C++ 标准在这一点上的规定,但我相信定义一些空结构/对象的大小有助于引用管理,以避免对不同连续对象的两个引用,第一个是空的,得到同一个地址。如果引用是经常使用隐藏指针实现的,确保不同的地址将有助于比较它们。

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).

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