Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal mechanism of sizeof in C?

I use sizeof to get size of a struct in C, but the result I got is unexpected.

struct sdshdr {
    int len;
    int free;
    char buf[];
};


int main(){
    printf("struct len:%d\n",(sizeof(struct sdshdr)));
    return 0;
} //struct len:8, with or without buf

my question is why does buf not occupy any space and why is the size of the int type still 4 on a 64-bit CPU?

here is the output from gcc -v:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix  
like image 533
ssj Avatar asked Jul 09 '15 13:07

ssj


People also ask

How sizeof operator works internally in C?

The sizeof operator applied to a type name yields the amount of memory that can be used by an object of that type, including any internal or trailing padding. The result is the total number of bytes in the array. For example, in an array with 10 elements, the size is equal to 10 times the size of a single element.

What is the use of sizeof () in C?

The sizeof operator is the most common operator in C. It is a compile-time unary operator and used to compute the size of its operand. It returns the size of a variable. It can be applied to any data type, float type, pointer type variables.

What is the output of sizeof () for C?

The C standard says the type of the result of sizeof is size_t (§6.5. 3.4/5).

What is sizeof int in C?

sizeof(* int) returns the size of the address value, that is, a byte. address that points to a byte position in memory that stores an int. value. The address values are typically 4 byte integers themselves on a. 32 bit system, so sizeof(*int) would return 4.


2 Answers

The [] is a flexible array member. They do not count towards the total size of the struct, because the C standard explicitly says so:

6.7.2.1/18

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply.

This is intentional by design, because the purpose of a flexible array member is to allow you to allocate trailing data dynamically after the struct. (When the struct is a file header, protocol header etc.)

Example including discussion about non-standard gcc extensions and the old pre-C99 "struct hack".

like image 111
Lundin Avatar answered Oct 16 '22 16:10

Lundin


From C99 onwards the size of an array at the end of a struct may be omitted. For purposes of sizeof(struct) this array will appear to have zero size (although its presence may add some padding to the struct), but the intent is for its length to be flexible, i.e., when allocating space for the struct one must allocate the desired amount of extra space for the array at the end. (To avoid going out of bounds, the actual allocated length of the array should be stored somewhere.)

Before C99 it was a fairly common hack to have an array of size 1 (or 0 where allowed by the compiler) at the end of a struct and then allocate more space for it, so C99 made this practice explicitly allowed by introducing the flexible array member with no size given.

like image 12
Arkku Avatar answered Oct 16 '22 16:10

Arkku