Question
I am compiling the following C program in Dev-C++ on Windows:
#include <stdio.h>
int main(void) {
int x = 5;
printf("%d and ", sizeof(x++));
printf("%d\n", x);
return 0;
}
I expected x to become 6 after the call containing sizeof(x++), but the program prints:
4 and 5
Why does x not increment when used inside sizeof?
Short Answer
By the end of this page, you will understand that sizeof usually determines the size of a type without evaluating its expression operand. That is why sizeof(x++) returns the size of int, but the side effect of x++ never happens, so x stays 5. You will also learn the important exception involving variable length arrays.
Concept
In C, sizeof is an operator that tells you how many bytes a type or object occupies.
For example:
sizeof(int)
sizeof x
sizeof(x)
all ask for a size in bytes.
The key idea is this:
sizeofusually does not evaluate the expression you put inside it.- It only uses that expression to determine its type.
- Since the expression is not executed, any side effects inside it do not happen.
That is exactly what happens here:
sizeof(x++)
x++ is a post-increment expression. Normally, evaluating it would:
- produce the current value of
x - increment
xafterward
But inside sizeof, the expression is typically not evaluated at all. C only checks the type of x++, which is int, and returns sizeof(int).
Mental Model
Think of sizeof as asking a librarian:
"How big is a book of this category?"
The librarian does not need to read the whole book to answer. They just look at the label or classification.
In the same way, sizeof(x++) does not "run" the increment. It simply looks at the expression and says:
x++has typeint- an
intis 4 bytes here
So sizeof answers 4 and never performs the ++.
Another way to think about it:
x++is an action with a side effectsizeof(...)usually asks only for type/size information- if no action is executed, no side effect occurs
Syntax and Examples
Core syntax
sizeof(type)
sizeof expression
Examples:
sizeof(int)
sizeof(double)
sizeof x
sizeof(x + 1)
Example 1: Simple variable
#include <stdio.h>
int main(void) {
int x = 5;
printf("%zu\n", sizeof(x));
return 0;
}
This prints the number of bytes used by x's type, which is usually the size of int.
Example 2: Expression inside sizeof
#include
{
x = ;
(, (x + ));
(, x);
;
}
Step by Step Execution
Consider this program:
#include <stdio.h>
int main(void) {
int x = 5;
size_t s = sizeof(x++);
printf("size = %zu, x = %d\n", s, x);
return 0;
}
Step-by-step
1. int x = 5;
A variable x is created and initialized to 5.
2. size_t s = sizeof(x++);
C looks at x++ only to determine its type.
xis anintx++also has typeintsizeof(int)is usually4
So gets the value .
Real World Use Cases
Understanding this behavior is useful in several practical situations.
1. Writing safe macros
C codebases often use macros that depend on sizeof:
#define ARRAY_BYTES(arr) (sizeof(arr))
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof((arr)[0]))
These work because sizeof can inspect types and sizes without evaluating expressions in the usual case.
2. Allocating memory
Developers often write:
int *p = malloc(10 * sizeof(*p));
This is useful because sizeof(*p) gives the size of the pointed-to type without dereferencing memory in the runtime sense.
3. Avoiding side-effect confusion
If you accidentally write code like this:
sizeof(i++)
expecting i to change, your program logic will be wrong. Understanding the rule helps you avoid subtle bugs.
4. Reading unfamiliar C code
In real projects, you will often see expressions placed inside for type-based sizing. Knowing that they are usually not evaluated helps you read code correctly.
Real Codebase Usage
In real C projects, sizeof is commonly used in patterns like these.
Type-safe allocation
int *arr = malloc(count * sizeof(*arr));
Why developers like this:
- it avoids repeating the type name
- if the variable type changes later, the
sizeofpart stays correct
Struct sizing
struct User *u = malloc(sizeof(*u));
This is clearer and less error-prone than manually writing the struct type again.
Array length macros
#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
This works for actual arrays, not pointers.
Guarding against logic mistakes
Experienced developers avoid writing expressions with side effects inside sizeof, even though they know those expressions are usually not evaluated. For example, they prefer not to write:
(x++)
Common Mistakes
1. Expecting side effects to happen
Broken expectation:
int x = 5;
size_t s = sizeof(x++);
printf("%d\n", x); // still 5, not 6
How to avoid it
Do not place increments, decrements, assignments, or function calls inside sizeof if you expect them to run.
2. Using the wrong printf format specifier
Broken code:
printf("%d\n", sizeof(x));
Why it is a problem:
sizeofreturnssize_t%dis forint
Better:
printf("%zu\n", sizeof(x));
3. Confusing arrays and pointers
Broken assumption:
Comparisons
sizeof vs normal evaluation
| Expression | Is it evaluated? | Side effects happen? | Result |
|---|---|---|---|
x++ | Yes | Yes | Old value of x, then increment |
sizeof(x++) | Usually no | No | Size of the type of x++ |
sizeof(int) | No runtime evaluation | No | Size of int |
sizeof on a type vs an expression
Cheat Sheet
Quick rules for sizeof
sizeofreturns the size in bytes.- The result type is
size_t. - Use
%zuto print asizeofresult. sizeofusually does not evaluate its expression operand.- Side effects inside
sizeofusually do not happen. - Exception: variable length arrays can require runtime evaluation.
Common forms
sizeof(int)
sizeof x
sizeof(x)
sizeof(x + 1)
Important example
int x = 5;
size_t s = sizeof(x++);
After this:
x == 5
because x++ was not evaluated.
FAQ
Why does sizeof(x++) not change x in C?
Because sizeof usually does not evaluate its operand expression. It only determines the expression's type and returns that type's size.
Does sizeof ever evaluate its operand?
Usually no. The important exception is when variable length arrays are involved, because their size may need runtime evaluation.
What does sizeof(x++) actually return?
It returns the size in bytes of the type of x++. If x is an int, that is typically the same as sizeof(int).
Why did my program print 4 and 5?
4 is the typical size of int on your system, and 5 remains unchanged because x++ was not executed.
Should I use %d to print sizeof results?
No. The correct format specifier is because returns .
Mini Project
Description
Build a small C program that reports the sizes of different types and expressions, while showing that side effects inside sizeof usually do not happen. This reinforces how sizeof works in practical code and helps you practice printing size_t correctly.
Goal
Create a program that compares normal expression evaluation with sizeof behavior and prints the results clearly.
Requirements
- Declare at least one
intvariable and one array. - Print the size of an
int, the size of the variable, and the size of the array. - Demonstrate that
x++increments normally outsidesizeof. - Demonstrate that
x++does not incrementxinsidesizeof. - Use the correct
printfformat specifier forsizeofresults.
Keep learning
Related questions
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
C Pointer to Array vs Array of Pointers: How to Read Complex Declarations
Learn the difference between pointer-to-array and array-of-pointers in C, plus a simple rule for reading complex declarations correctly.