Can there be a C++ type that takes 0 bytes

2020-03-02 03:14发布

I'm trying to declare a C++ variable that takes up zero bytes. Its in a union, and I started with the type as int[0]. I don't know if that is actually zero bytes (although sizeof(int[0]) was 0). I need a better way to declare a 0 byte type, and hopefully one that can be typedefed to something like nullType or emptyType. The variable is in a union, so in the end memory is reserved anyway. I tried void on the off chance it would work, but C++ complained. I'm using Ubuntu 10.10, with a current version of the kernel, and an up-to-date GCC. Here's the union:

union RandomArgumentTypesFirst
{
    uint uintVal;
    nullType nullVal;
}

And here is the typedef:

typedef int[0] nullType;

The compiler says this about the typedef:

error: variable or field ‘nullVal’ declared voidmake[2]:

When I typed in int[0], it worked. Any suggestions?

EDIT: As @fefe said in the comments, the int[0] may be provided as an extension by the compiler. GCC's website says that the compiler has many extensions by default.

6条回答
叼着烟拽天下
2楼-- · 2020-03-02 03:28

A variable in C++ can never take zero bytes. Every object must have unique address, which is not possible if the size is zero.

By the way,int[0] is illegal in Standard C++. If you're using GCC, compile it with -pedantic option, you will get this warning:

warning: ISO C++ forbids zero-size array 'x' [-pedantic]

Also, the syntax for typedef should be this:

  typedef int array[100]; //zero cannot be size - illegal!
查看更多
放荡不羁爱自由
3楼-- · 2020-03-02 03:40

You cannot instantiate any data type in C++ that takes up zero bytes. The Standard dictates than an empty class, such as:

class Empty {};

...will result in the following being true:

Empty emp;
assert( sizeof(emp) != 0 );

The reason for this is so that you can take the address of the object.

EDIT: I originally said the sizeof would be 1, but per @Als' comment, I have found the relevant passage in the Standard, and it is indeed simply non-zero:

[Classes] §9/3

Complete objects and member subobjects of class type shall have nonzero size

查看更多
家丑人穷心不美
4楼-- · 2020-03-02 03:41

The standard explicitly prohibits the existence of an instance of a type with size 0, the reason is that if an object could have size 0, then two different objects could be located at the exact same address. An empty struct, for example, will be forced to have size > 0 to comply with that requirement even if when used as base of a different type, the compiler can have it have size == 0.

What is it that you want to do with an empty class?

查看更多
可以哭但决不认输i
5楼-- · 2020-03-02 03:47

The typedef is misspelled:

typedef int nullType[0];

As others have pointed out, you cannot have an object of size 0; However, compilers can (and frequently do) provide the Empty Base Class optimization.

查看更多
Rolldiameter
6楼-- · 2020-03-02 03:48

It sounds like you want std::optional.
It won't have a sizeof 0, but that's not important for expressing an empty value.


On a related note, there is C++ proposal (P0146R1) to make void a regular type.
The paper goes on to discuss why even sizeof(void) can't be 0.

Why Isn't sizeof(void) Equal to 0?

One suggestion that has repeatedly come up is to have sizeof(void) report 0 and to allow multiple instances to share the same address. This would prevent users from having to use tricks akin to the empty base optimization in order to make more optimal usage of memory. Ideally, this would be the case, however such a change to the language is both vast and out of scope of the proposal. Allowing a type to have a 0 size and to allow separate instances to share an address implies drastic and subtle breaking changes to existing code. For instance, if you were to make an array of such a void type, a pointer, at least in the traditional sense, would no longer be able to be used as an iterator into that array (notably meaning that generic code which relies on this would now fail for such a size 0 type). As well, any code that relies on an object's type and address as unique would fail for void types, even though it is otherwise perfectly acceptable. Finally, if such a size were permitted for void, it should really be allowed for any type, including user-defined types. Having a special rule for void would make one more thing to have to think about and deal with differently for void types. Instead, this proposal opts to leave the size of void unspecified and thereby governed by existing language rules. In practice, it is expected that void will likely be size 1 in most implementations, though this is not required. If an eventual change were made to the language to allow for size 0 types, then void would be able to implicitly take advantage of that.


Although this question is targeted to C++, it should be noted that an empty struct in C may result in a sizeof of 0. This however, is undefined behavior.

If the struct-declaration-list contains no named members, the behavior is undefined.

查看更多
不美不萌又怎样
7楼-- · 2020-03-02 03:49

The C++ standard demands explicitly that every type have size at least 1. This is intimately tied to the requirement that each object have a unique address (consider Foo x[10] if Foo had size zero).

查看更多
登录 后发表回答