# C: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]

**Code:** `format expects argument of type` · **Category:** C/C++ · **Seen on:** C/C++, GCC, Clang

The `printf`/`scanf` format specifier does not match the argument's type, which is undefined behaviour and prints garbage or crashes.

## Meaning

`%d` is `int`, `%ld` is `long`, `%lld` is `long long`, `%zu` is `size_t`, `%f`/`%lf` are `double`, `%s` is `char*`, and `%p` expects `void*`. A wrong specifier reads the wrong number of bytes from the argument list. In C++ prefer `std::cout` or `std::format`.

## Common causes

- `%d` used with `long`, `size_t` or `long long`
- `%s` given a `std::string` instead of `c_str()`
- Missing argument for a specifier, or an extra one
- `%f` used with `float` in `scanf` (needs `%f` for float but `%lf` for double)
- `%p` given a non-void pointer without a cast

## Quick fix

1. Use `%zu` for `size_t`, `%ld` for long, `%lld` for long long
2. Pass `str.c_str()` for `%s`
3. Compile with `-Wall -Wformat=2`

## Detailed fix by platform

### GCC / Clang

1. Add `-Wall -Wextra -Wformat=2` and treat as error: `-Werror=format`
2. In C++20 use `std::format("{}", x)`, which checks types at compile time

## Code examples

### Matching specifiers

```c
#include <stdio.h>
#include <stddef.h>

int main(void) {
    long big = 1234567890123L;
    size_t n = 42;
    printf("%ld %zu\n", big, n);    /* not %d for either of them */
    return 0;
}
```

## How to diagnose

1. **Specifier** — Which % matches which argument?
2. **Types** — Exact type of each argument?
3. **Count** — Same number of specifiers and arguments?

---
Source: [WhatIsMyError](https://whatismyerror.com/errors/cpp/format-expects-argument)
