C++/c++ faq

Advertisement


Question
why the size of empty structure in C++ is 1 byte and in C its zero?

Answer
Are you sure this is correct for C? The C99 standard states in section 6.2.6.1 (Representation of types, General):

Paragraph 2:

       "Except for bit-fields, objects are composed
        of contiguous sequences of one or more bytes,
        the number, order, and encoding of which are
        either explicitly specified or
        implementation-defined."

Hence the size of an object *must* be at least 1 in C, unless it is a bit field. So although the size of an object of an empty struct type in C may be zero in some implementations, strictly I suppose it is the definition of the empty struct that is in error. In fact although as far as I can tell the C standard says nothing explicitly that forbids empty struct (or union) definitions, apart from the above paragraph, it is implied by the syntax of struct and union definitions, which in part is as follows:

   struct-or-union-specifier:
       struct-or-union opt-identifier '{' struct-declaration-list '}'
       struct-or-union identifier

   struct-or-union:
       "struct"
       "union"

   struct-declaration-list:
       struct-declaration
       struct-declaration-list struct-declaration

     .
     .
     .

Thus we have either the full struct or union definition, which may optionally be named with an identifier, or we have just a forward declaration.

A full definition, after the keyword "struct" or "union" and the optional identifier, consists of a struct-declaration-list in curly braces ( '{' and '}' ). This list consists of either 1 single struct-declaration, or more than 1 struct-declaration. Hence the struct-declaration-list cannot be empty.

In C there is no reason for an empty struct. In C++ there are several, usually relating to the type being used as a base class, or maybe as class templates, e.g. deriving types from a set of template parameters, none of which uses are relevant to C.

Thus in C++ the case of potentially zero-sized class types (which include structs and unions) had to be addressed. In C and C++ objects of struct, union and, for C++, class types can have their address taken. This begs the question: if a class (or struct) has no members, and therefore logically has a size of zero, where in memory would an object of such a type exist? Would all such zero sized objects share the same address? Etc.

Further, for pointer arithmetic to work without complexity each object has to have its own address. A common use of pointer arithmetic being built in arrays:

   MyType  myArray[5]; // array of 5 MyType objects

   myArray[2].DoSomethingInteresting();

     .
     .
     .

The expression myArray[2] is equivalent to *(myArray+2), that is add 2*sizeof(MyType) to the byte address (i.e. char*) value of myArray and return the value of what is at that location (remember array names in C and C++ represent the address of the first (zeroth) element of the array). If sizeof(MyType) is zero then all elements will be at the same location (try using 0 for sizeof(MyType) in 2*sizeof(MyType)), and we cannot distinguish one object in the array from another.

Hence in C++ _all_ objects have to exist in memory somewhere at their own unique address. As soon as something has an (unique) address it has a non-zero size. This leads to the rule that objects (and class member sub-objects - i.e. class data members) of logically zero-sized class types have a size of (at least) 1. However if such a type is used as base class of some other type then its size may be zero. This is because the final derived type will have to have a size of at least one and the address of the logically-zero sized base sub-object can be the same as that of the derived type object - or maybe some other base sub-object. Unique addresses only being required for whole objects (and class members as these also can have their address, in the form of pointer to members, taken). The rule is part of clause 9 Classes, paragraph 3, which starts:

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

This sentence finishes with a reference to note 94 which reads:

       "Base class subobjects are not so constrained."


Oh, and the syntax for class types in C++ has an optional component between the curly braces of a class type definition:

   classspecifier:
       classhead { opt-memberspecification }

So we start with the class head which is "class" "struct" or "union" plus the type name and any base class specification etc.

Next we have the body of the definition in curly braces, as for the C struct case. However the member specification part between the braces is optional so in C++ we can have an empty class, struct or union definition according to the syntax.

Hope this helps  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.