Question

Why `sizeof(x++)` Does Not Increment `x` in C

csizeof

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:

  • sizeof usually 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:

  1. produce the current value of x
  2. increment x afterward

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).

So if int is 4 bytes on your system, the result is 4, and x remains 5.

Why this matters

This is important because many C operators and constructs look like they "run" code, but some operate only at the type level or compile-time-like level. Understanding this helps you avoid bugs and write clearer code.

Important exception

There is one important exception in C: variable length arrays (VLAs). When sizeof is applied in situations involving VLAs, the expression may need to be evaluated because the size is determined at runtime.

For ordinary expressions like sizeof(x++) where x is an int, no increment happens.

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 type int
  • an int is 4 bytes here

So sizeof answers 4 and never performs the ++.

Another way to think about it:

  • x++ is an action with a side effect
  • sizeof(...) usually asks only for type/size information
  • if no action is executed, no side effect occurs
Take Quiz

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 <stdio.h>

int main(void) {
    int x = 5;
    printf("%zu\n", sizeof(x + 10));
    printf("%d\n", x);
    return 0;
}

x + 10 is not evaluated. sizeof just determines the type of the expression, which is still int here.

Example 3: Post-increment inside sizeof

#include <stdio.h>

int main(void) {
    int x = 5;
    printf("%zu and %d\n", sizeof(x++), x);
    return 0;
}

Output is typically:

4 and 5

Why?

  • sizeof(x++) asks for the size of the expression's type
  • it does not execute x++
  • x is still 5

About printing sizeof

The result type of sizeof is size_t, so the correct format specifier is usually %zu:

printf("%zu\n", sizeof(x));

Using %d may work on some systems, but it is not the correct type-safe choice.

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.

  • x is an int
  • x++ also has type int
  • sizeof(int) is usually 4

So s gets the value 4.

What does not happen:

  • x++ is not executed
  • x is not incremented

So x is still 5.

3. printf("size = %zu, x = %d\n", s, x);

This prints something like:

size = 4, x = 5

Important takeaway

Even though x++ normally changes x, putting it inside sizeof prevents that normal evaluation in most cases.

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 sizeof for type-based sizing. Knowing that they are usually not evaluated helps you read code correctly.

Take Quiz

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 sizeof part 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:

sizeof(x++)

because it is confusing to readers.

Instead, they keep sizeof expressions simple and side-effect free.

Validation and clarity

In production code, clarity matters. A developer reading:

sizeof(buffer)

immediately understands the intention. But reading:

sizeof(get_value())

may raise questions about whether get_value() runs. Keeping sizeof operands simple reduces confusion and maintenance cost.

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:

  • sizeof returns size_t
  • %d is for int

Better:

printf("%zu\n", sizeof(x));

3. Confusing arrays and pointers

Broken assumption:

void print_len(int arr[]) {
    printf("%zu\n", sizeof(arr) / sizeof(arr[0]));
}

Inside a function parameter, arr is actually a pointer, not an array, so this does not give the array length.

4. Assuming sizeof(int) is always 4

Many systems use 4-byte int, but the C standard does not require it to always be 4.

Safer mindset:

  • sizeof(int) is implementation-dependent
  • check, do not assume

5. Forgetting the VLA exception

Most of the time, sizeof does not evaluate its operand. But with variable length arrays, runtime evaluation may be involved.

For beginners, the safe rule is:

  • usually, sizeof does not evaluate expressions
  • but VLAs are a special case worth remembering

Comparisons

sizeof vs normal evaluation

ExpressionIs it evaluated?Side effects happen?Result
x++YesYesOld value of x, then increment
sizeof(x++)Usually noNoSize of the type of x++
sizeof(int)No runtime evaluationNoSize of int

sizeof on a type vs an expression

FormExampleMeaning
sizeof(type)sizeof(int)Size of that type
sizeof expressionsizeof xSize of the expression's type
sizeof(expression)sizeof(x + 1)Same idea, with parentheses for grouping

sizeof vs strlen

These are often confused.

Featuresizeofstrlen
Works onTypes or objectsNull-terminated strings
Evaluates string contents?NoYes
ReturnsBytes occupiedNumber of characters before \0
Examplesizeof("cat") is often 4strlen("cat") is 3

sizeof with arrays vs pointers

CaseExampleTypical result
Arrayint a[10]; sizeof(a)Total bytes of all 10 elements
Pointerint *p; sizeof(p)Size of the pointer itself

This difference is very important in real C programs.

Take Quiz

Cheat Sheet

Quick rules for sizeof

  • sizeof returns the size in bytes.
  • The result type is size_t.
  • Use %zu to print a sizeof result.
  • sizeof usually does not evaluate its expression operand.
  • Side effects inside sizeof usually 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.

Correct printing

printf("%zu\n", sizeof(x));

Good practice

Prefer clear operands:

sizeof(buffer)
sizeof(*ptr)
sizeof(struct Node)

Avoid confusing code like:

sizeof(i++)
sizeof(func())

Memory allocation pattern

int *p = malloc(n * sizeof(*p));

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 %zu because sizeof returns size_t.

Is sizeof(int) always 4?

No. It is implementation-dependent. Many modern systems use 4-byte int, but the language standard does not guarantee that exact size.

Is sizeof a function?

No. It is an operator in C.

Can I safely put function calls inside sizeof?

They usually will not run, but doing so is often confusing. It is better style to avoid expressions with side effects inside sizeof.

Take Quiz

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 int variable 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 outside sizeof.
  • Demonstrate that x++ does not increment x inside sizeof.
  • Use the correct printf format specifier for sizeof results.
Take Quiz

Keep learning

Related questions

View more