parameters - What arguments does the sizeof operator take in C? - Stack Overflow
How sizeof works in C/C++
what's the mechanism of sizeof() in C/C++? - Stack Overflow
c - sizeof style: sizeof(type) or sizeof variable? - Software Engineering Stack Exchange
Videos
sizeof isn't a function, it's a keyword. You could drop the parentheses and it would work just fine. Because it's not a function, it works with any type or object that you give it - it's much more flexible than a function.
sizeof is not a function; it's an operator. It can be used in two ways: as sizeof(typename) and as sizeof expression. The parentheses are required when used with a type name. Parentheses are not needed when the operand is an expression, though for clarity's sake many programmers will parenthesize the expression regardless. Note that unlike most programming languages operators, sizeof expression does not evaluate its argument under normal circumstances, i.e., when its operand is not a C99 variable-length array.
You know, there's a reason why there are standard documents (3.8MB PDF); C99, section 6.5.3.4, §2:
The
sizeofoperator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
In response to ibread's comment, here's an example for the C99 variable length array case:
#include <stdio.h>
size_t sizeof_int_vla(size_t count)
{
int foo[count];
return sizeof foo;
}
int main(void)
{
printf("%u", (unsigned)sizeof_int_vla(3));
}
The size of foo is no longer known at compile-time and has to be determined at run-time. The generated assembly looks quite weird, so don't ask me about implementation details...
sizeof is an operator, not a function.
It's usually evaluated as compile time - the exception being when it's used on C99-style variable length arrays.
Your example is evaluating sizeof(int), which is of course known at compile time, so the code is replaced with a constant and therefore the ++ doesn't exist at run-time to be executed.
int i=0;
cout << sizeof(++i) << endl;
cout << i << endl;
It's also worth noting that since it's an operator, it can be used without the brackets on values:
int myVal;
cout << sizeof myVal << endl;
cout << sizeof(myVal) << endl;
Are equivalent.
I perfer sizeof(variable) over sizeof(type). Consider:
int a1;
float a2;
memset(&a1,0,sizeof(a1));
memset(&a2,0,sizeof(a2));
vs.
int a1;
float a2;
memset(&a1,0,sizeof(int));
memset(&a2,0,sizeof(float));
In the first case, it's easy to verify that the right sizes are being passed to memset. In the second case, you need to constantly review top and bottom sections to make sure you are consistent.
The preference (as always) is to reflect your intention as directly as possible.
Is the intention to operate against an existing variable's memory? If so, then use sizeof(variable), as this shows as closely as possible that it's the variable itself's memory that you care about.
Is the intention to perform some calculation on the type, for example to determine how much memory should be allocated for a new instance? If so, then use sizeof(type).
That is, I prefer
struct foo *bar;
bar = (struct foo *) malloc(sizeof(struct foo));
over
bar = (struct foo *) malloc(sizeof(*bar));
as the latter case looks like you're trying to access a variable that doesn't exist, yet.
On the other hand, I prefer
char Buffer[256];
memset(Buffer, 0, sizeof(Buffer));
over
char Buffer[256];
memset(Buffer, 0, 256 * sizeof(char));
as the intention is clearly to zero-fill the contents of the variable, so it's the variable we should operate against. Trying to use the type metadata just confuses things, here.
Answer: sizeof returns the size of the type in bytes.
Example: sizeof(char) is 100% guaranteed to be 1, but this does not mean, that it's one octet (8 bits).
Proved by the standard:
in 6.5.3.4, point 2:
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
...
When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array) When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.
Also, in Section 3.6, point 3:
A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined
sizeof always returns size as the number of bytes. But according to wikipedia:
In the programming languages C and C++, the unary operator sizeof is used to calculate the size of any datatype, measured in the number of bytes required to represent the type. A byte in this context is the same as an unsigned char, and may be larger than 8 bits, although that is uncommon.
Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
The sizeof way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof will return the pointer's size, instead of the array's.
Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.
Test:
#include <stdio.h>
#include <stdlib.h>
void printSizeOf(int intArray[]);
void printLength(int intArray[]);
int main(int argc, char* argv[])
{
int array[] = { 0, 1, 2, 3, 4, 5, 6 };
printf("sizeof of array: %d\n", (int) sizeof(array));
printSizeOf(array);
printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
printLength(array);
}
void printSizeOf(int intArray[])
{
printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}
void printLength(int intArray[])
{
printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}
Output (in a 64-bit Linux OS):
sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2
Output (in a 32-bit windows OS):
sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1