Is it possible for the sizeof operator to ever return 0 (zero) in C or C++? If it is possible, is it correct from a standards point of view?
-
3I came across this: http://msdn.microsoft.com/en-us/library/4s7x1k91(VS.71).aspx which states that sizeof can NEVER return 0 but I'm not sure if this is just a Microsoft implementation constraint (and seems to be C++ specific). – TheJuice Apr 13 '10 at 18:19
-
I wonder if the sizeof an abstract base class can be `0` (it's not possible to declare an instance of them so that objection wouldn't apply) – M.M May 28 '16 at 10:03
-
If you ever need the true size of a struct in C++ (to distinguish between a truly empty struct vs one with a char in it), you can defeat sizeof's lie with `std::is_empty_v
? 0 : sizeof(T);`. – Dwayne Robinson Dec 20 '19 at 08:05
10 Answers
In C++ an empty class or struct has a sizeof
at least 1 by definition. From the C++ standard, 9/3 "Classes": "Complete objects and member subobjects of class type shall have nonzero size."
In C an empty struct is not permitted, except by extension (or a flaw in the compiler).
This is a consequence of the grammar (which requires that there be something inside the braces) along with this sentence from 6.7.2.1/7 "Structure and union specifiers": "If the struct-declaration-list contains no named members, the behavior is undefined".
If a zero-sized structure is permitted, then it's a language extension (or a flaw in the compiler). For example, in GCC the extension is documented in "Structures with No Members", which says:
GCC permits a C structure to have no members:
struct empty { };
The structure will have size zero. In C++, empty structures are part of the language. G++ treats empty structures as if they had a single member of type
char
.

- 333,147
- 50
- 533
- 760
-
1
-
2@TheJuice: the grammar requires that there be something in the struct definition, but I think you might be able to get away (grammar-wise) with just a semi-colon (I'm not sure about that - reading BNF isn't one of my strong suits). However, if you don't have anything with a name inside the struct definition, then you're in undefined behavior territory (which really buys you nothing - you can't count on it to do anything sensible). – Michael Burr Apr 13 '10 at 18:37
-
6@Michael Burr: Actually, the grammar itself already prohibits empty structs. An empty struct in C is immediately a syntax error, not a UB. The remark about "no named members - UB" is there to close a different loophole. You can declare `struct { int : 1 }` (i.e. an unnamed bitfield) to formally satisfy the grammar requirements. To outlaw things like that there's that extra remark there. – AnT stands with Russia Apr 13 '10 at 18:40
-
-
1@Andrey: `struct { char : 0; };` is even more empty. (GCC at least make your example the size of an `int`.) — hey, I tried this, and GCC *does* create a struct of size 0! G++ makes it size 1. – Potatoswatter Apr 13 '10 at 19:11
-
1@Potatoswatter: (While in aggressively pedantic mood...) In that case it should be `struct { int : 0; };`. C language does not allow bitfields of `char` type :) – AnT stands with Russia Apr 13 '10 at 19:14
-
2@Andrey: I see, C99 §6.7.2.1/4 "A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type." Also, I just tested the `int:1` way and GCC and G++ do make it size 1. Sorry about that. – Potatoswatter Apr 13 '10 at 19:26
-
@Potatoswatter: OK, I should've said "C language does not guarantee support for bitfields of `char` type" – AnT stands with Russia Apr 13 '10 at 19:29
-
2gcc does return 0 for a sizeof an empty struct;int main(){ printf("%i",sizeof(struct {})); } – flownt Oct 12 '10 at 10:24
-
1
-
@Owen: One reason for it might be to prevent distinct objects from having the same address. For example, if you have a struct that contained other empty structs it might cause problems/confusion with how to deal with those empty members. I'm not sure if there are other reasons - I'm actually even just guessing that this is a reason. . – Michael Burr May 27 '16 at 16:16
-
Yes, I think you're right. It would be impossible to create one using `malloc()`. – Owen May 27 '16 at 22:08
-
@MichaelBurr: The only problematic situations involving zero-size objects would be (1) whether their addresses might compare equal to other objects [IMHO their addresses should be allowed to be arbitrarily equal to any other object], or (2) what the effect of subtracting unequal pointers to zero-sized objects should be, and (3) whether implementations should be required to treat the difference between two equal pointers to zero-sized objects as zero, allowed to treat it as some possibly-arbitrary integer (this allowing (ptr+x)-ptr to yield x without regard for the size of `*ptr`), or... – supercat Jun 27 '18 at 21:38
-
...allowed to treat it in completely arbitrary fashion. IMHO, the tiny bit of extra complexity necessary to specify behavior in those cases is significantly outweighed by the fact that such specification would often eliminate the need for special code to handle degenerate cases. – supercat Jun 27 '18 at 21:40
sizeof
never returns 0
in C and in C++. Every time you see sizeof
evaluating to 0
it is a bug/glitch/extension of a specific compiler that has nothing to do with the language.

- 312,472
- 42
- 525
- 765
-
3
-
8@MK: The language standard is the refernce. There's no single place there. It all derives from such facts that any object type by definition has non-zero size in both C or in C++. The fact that you can't apply `sizeof` to incomplete types also plays a role. And so on. – AnT stands with Russia Apr 13 '10 at 18:42
-
1So, in terms of votes, which question should stackoverflow rank higher: +8/-0 or +19/-11 ? One is controversial, the other is a consensus, nudge-nudge. – wilhelmtell Apr 13 '10 at 20:07
-
GCC 4.5.x returns zero for sizeof(
) when used inside the declaration of class. This makes sense to me since there is no way it can know the class' size at that time. – everclear Jul 13 '13 at 16:16 -
1@everclear: Firstly, that is not entirely accurate. "Inside the declaration of a class" there are places where the class is supposed to be seen as complete type. That includes default arguments, for one example. If your version of GCC returns zero from `sizeof` in such contexts, it is hopelessly broken and useless. – AnT stands with Russia Jul 13 '13 at 18:23
-
Secondly, outside of those places applying `sizeof` to class type inside class definition is ill-formed. It is an error. In one of the recent answers (http://stackoverflow.com/questions/17585191/incomplete-type-class-usage-before-definition-vs-forward-declaration/17585259#17585259) I experimented with GCC 4.3.2 and 4.7.2 on ideone.com and both compliantly reported errors for each instance of such `sizeof` usage. Why your version of GCC suddenly evaluates to zero in such cases is not clear to me. – AnT stands with Russia Jul 13 '13 at 18:25
-
Hi Andrey, thanks for your comment. I have not tried to use sizeof(
) as a default argument, so no way for me to check it. I used it in an inner POD class declaration of a memory pool item for type – everclear Jul 14 '13 at 21:04. However no compile error there! I ended up declaring the memory pool item outside of . Perhaps the reason for the flaw is the target (arm-none-eabi), which is probably not as well maintained???
Every object in C must have a unique address. Worded another way, an address must hold no more than one object of a given type (in order for pointer dereferencing to work). That being said, consider an 'empty' struct:
struct emptyStruct {};
and, more specifically, an array of them:
struct emptyStruct array[10];
struct emptyStruct* ptr = &array[0];
If the objects were indeed empty (that is, if sizeof(struct emptyStruct) == 0
), then ptr++ ==> (void*)ptr + sizeof(struct emptyStruct) ==> ptr
, which doesn't make sense. Which object would *ptr
then refer to, ptr[0]
or ptr[1]
?
Even if a structure has no contents, the compiler should treat it as if it is one byte in length in order to maintain the "one address, one object" principle.
The C language specification (section A7.4.8) words this requirement as
when applied to a structure or union, the result (of the
sizeof
operator) is the number of bytes in the object, including any padding required to make the object tile an array
Since a padding byte must be added to an "empty" object in order for it to work in an array, sizeof()
must therefore return a value of at least 1 for any valid input.
Edit:
Section A8.3 of the C spec calls a struct without a list of members an incomplete type, and the definition of sizeof
specifically states (with emphasis added):
The operator (sizeof) may not be applied to an operand of function type, or of incomplete type, or to a bit-field.
That would imply that using sizeof
on an empty struct would be equally as invalid as using it on a data type that has not been defined. If your compiler allows the use of empty structs, be aware that using sizeof
on them is not allowed as per the C spec. If your compiler allows you to do this anyway, understand that this is non-standard behavior that will not work on all compilers; do not rely on this behavior.
Edit: See also this entry in Bjarne Stroustrup's FAQ.

- 43,959
- 6
- 69
- 99
-
That logic is why C++ requires that sizeof never return 0. But according to Michael Burr's answer, an empty struct in C is undefined behavior. Which probably explains why gcc's implementation of empty structs violates all of your assumptions. – Dennis Zickefoose Apr 13 '10 at 19:55
-
@bta: What you said might apply to C++. In C an empty struct (as in your example) is simply a constraint violation, a syntax error. So formally the issue of "size of empty struct" does not even exist in C. – AnT stands with Russia Apr 13 '10 at 20:20
-
1@AndreyT: I realize that an empty struct is invalid in C, I just wanted to show that even if you *could* do it, the definition of `sizeof` would still return non-zero. – bta Apr 14 '10 at 00:09
-
@bta Nicely worded. You should just add that C chose to solve this problem by disallowing empty structs altogether, while C++ chose to solve it by defining them to be of size of at least 1. – wilhelmtell Apr 14 '10 at 01:06
-
@bta: gcc choses to allow empty structs in C, and assigns them a size of zero. – Dennis Zickefoose Apr 14 '10 at 02:04
-
@Dennis: Hmm, that's an interesting choice on gcc's part. In any case, such behavior would seem to violate the C standard (as I read it), so definitely do not write code assuming this behavior. – bta Apr 14 '10 at 02:20
-
Objects are not always required to have a unique address: `int a[1]; assert(&a == &a[0]);` or `struct T { int n; } obj; assert(&obj == &obj.n);` (for those examples, in fact, it's required that the have the same address). – Apr 15 '10 at 07:38
-
@Roger Pate: Your array example isn't really different objects, it's just C's "syntactic sugar" for expressing the same object in two ways. The struct example is a different case because it is a container/contents relationship. `&obj` and `&obj.n` have different types of different lengths, so the address can be used both ways without confusion (same with fields in a union). The uniqueness requirement applies to objects *of the same data type*, so that (for example) the same pointer could not refer to two distinct `struct emptyStruct` objects (`&array[1]` cannot equal `&array[2]`). – bta Apr 15 '10 at 16:33
-
The array example really does have two different objects (`sizeof(a) != sizeof(a[0])` as you pointed out too) and it's really the same case as the struct. If you said "every object of the same data type must have a unique address" in the answer, it would be an improvement. – Apr 15 '10 at 16:56
Empty structs, as isbadawi mentions. Also gcc allows arrays of 0 size:
int a[0];
sizeof(a);
EDIT: After seeing the MSDN link, I tried the empty struct in VS2005 and sizeof did return 1. I'm not sure if that's a VS bug or if the spec is somehow flexible about that sort of thing

- 1
- 1

- 169,610
- 28
- 168
- 175
-
This is wrong. See the comments by @AndreyT on the answer of @isbadawi. – wilhelmtell Apr 13 '10 at 18:38
-
5
-
@JohnDibling. You are right. But after more and more compilers allow it (clang also) it may become legal one day. When coding I would not bet either way. – Patrick Fromberg Jul 07 '19 at 16:20
-
@PatrickFromberg: Just an observation. I wrote that comment 9 years ago. Personally, I'm for (and always have been for) not letting the compiler tell me what's legal and what's not. – John Dibling Sep 12 '19 at 23:36
typedef struct {
int : 0;
} x;
x x1;
x x2;
Under MSVC 2010 (/Za /Wall):
sizeof(x) == 4
&x1 != &x2
Under GCC (-ansi -pedantic -Wall) :
sizeof(x) == 0
&x1 != &x2
i.e. Even though under GCC it has zero size, instances of the struct have distinct addresses.
ANSI C (C89 and C99 - I haven't looked at C++) says "It shall be possible to express the address of each individual byte of an object uniquely." This seems ambiguous in the case of a zero-sized object, since it arguably has no bytes.
Edit: "A bit-field declaration with no declarator, but only a colon and a width, indicates an unnamed bit-field. As a special case of this, a bit-field with a width of 0 indicates that no further bit-field is to be packed into the unit in which the previous bit-field, if any, was placed."

- 5,055
- 1
- 28
- 44
in my view, it is better that sizeof returns 0 for a structure of size 0 (in the spirit of c). but then the programmer has to be careful when he takes the sizeof an empty struct.
but it may cause a problem. when array of such structures is defined, then
&arr[1] == &arr[2] == &arr[0]
which makes them lose their identities.
i guess this doesnt directly answer your question, whether it is possible or not. well that may be possible depending on the compiler. (as said in Michael's answer above).

- 1,176
- 8
- 15
-
3it is not a matter of opinion here. there is an authority that has a final say here -- the standard -- and the question is about what the standard says about `sizeof` being zero. – wilhelmtell Apr 13 '10 at 18:44
-
2
-
2@Joshua: And your compiler has the potential to override your common sense. If you care at all about your code functioning across multiple compilers, your best bet is to forget what your common sense tells you and stick to the standard. – Dennis Zickefoose Apr 13 '10 at 20:13
-
2@Joshua sometimes the standard committee makes what looks like bad decisions. Yes, I agree. But this decision is not one of those bad decisions, if we really want to descend to futile endless opinionated discussions. The reason `sizeof()` an empty `struct` is not zero is so the standard can guarantee no two distinct instantiations of an empty `struct` (or two distinct empty `structs`) share the same memory address. In particular, this guarantees calls to `operator new()` will return a valid, unique memory address (or else fail altogether). – wilhelmtell Apr 14 '10 at 00:37
-
@Joshua Now, if the discussion is about whether we should listen to the standard or not then it is a futility of a different kind. The kind where we can either agree we should follow the standard, agree to disagree, or agree we shouldn't follow the standard and expect a velociraptor to come by and spontaneously bite each of our limbs off. In fact, while we're at it, why don't we disagree about speaking a common language? Disagree about relying our rationale on a common logic, or have common ethics? Surely there are better ways to get progress and order. Or, who needs these anyway? – wilhelmtell Apr 14 '10 at 00:52
-
@Joshua: Huh? How exactly does common sense override the standard? Are you saying that as long as it is common sense that something should work, the compiler will magically do it, *even if it's illegal according to the language standard*? I'm sorry, but programming doesn't work like that. What the compiler actually *does* overrides common sense *every single time*. And what the compiler actually does is dictated by the language standard. Common sense has no say whatsoever in this or any other language behavior question. – jalf Apr 17 '10 at 02:38
-
I'm saying that ridicules things in the standard eventually get replaced by compiler vendors. – Joshua Apr 17 '10 at 20:20
-
@jalf: The purpose of the Standard is to specify things that compilers must do to be *conforming*. The authors of the C Standard (and likely the C++ Standard as well) expressly acknowledge in the rationale that a compiler may be conforming and yet be of such poor quality as to be useless. The fact that the Standard may allow compilers to behave a certain way in a certain situation does not imply that it's possible that it would be possible for a compiler that is suitable for a particular purpose to behave that way (since such behavior may render the compiler unsuitable for that purpose). – supercat Jun 27 '18 at 21:46
Here's a test, where sizeof yields 0
#include <stdio.h>
void func(int i)
{
int vla[i];
printf ("%u\n",(unsigned)sizeof vla);
}
int main(void)
{
func(0);
return 0;
}

- 223,662
- 58
- 417
- 506
-
2I could be reading things wrong, but I believe that VLAs in C must have sizes greater than zero. "If the size is an expression that is not an integer constant expression: ... otherwise, each time it is evaluated it shall have a value greater than zero." – Dennis Zickefoose Apr 14 '10 at 09:41
-
Could be, gcc however, yields 0 - so "it is possible" - though maybe it's not correct. – nos Apr 14 '10 at 09:58
If you have this :
struct Foo {};
struct Bar { Foo v[]; }
g++ -ansi
returns sizeof(Bar) == 0. As does the clang & intel compiler.
However, this does not compile with gcc. I deduce it's a C++ extension.

- 5,904
- 6
- 26
- 28
struct Empty {
} em;
struct Zero {
Empty a[0];
} zr;
printf("em=%d\n", sizeof(em));
printf("zr=%d\n", sizeof(zr));
Result:
em=1
zr=0