narrowing conversion C/C++ Origin: Application & API C++11 and later Last updated 15 Oct 2026

C++: error: narrowing conversion of 'x' from 'int' to 'char' inside { } [-Wnarrowing]

Brace initialisation {} refuses conversions that can lose data, such as double to int or a runtime int to char.

Exact message you may see narrowing conversion ofnarrowing conversion of from 'int' to 'char' inside { }non-constant-expression cannot be narrowed from typeconstant expression evaluates to which cannot be narrowed
Seen on: C/C++ GCC Clang

Meaning

List-initialisation was designed to catch lossy conversions. Constants that fit are allowed (char c{65};), but a variable or an out-of-range literal is an error in C++11 and later. Use the right type, or make the conversion explicit with static_cast when you really want it.

Common causes

  • Initialising a smaller type from a variable with braces (int to char, long to int)
  • Braced initialisation of an integer from a floating-point value
  • Value outside the target type's range
  • Signed to unsigned conversion of a negative or non-constant value in {}

⚡ Quick fix

  1. Use the matching type (int instead of char)
  2. Add static_cast<T>(x) where narrowing is intended
  3. Use = initialisation only if you accept silent truncation (not recommended)

Detailed fix by platform

C++

  1. char c{static_cast<char>(n)}; makes the intent explicit
  2. Prefer auto or the exact type returned by the function you call

Code examples

Braces catch lossy conversions

cpp
int n = 300;
// char c{n};                       // error: narrowing conversion of 'n' from 'int' to 'char'
char c{static_cast<char>(n)};       // OK, truncation is explicit (value 44)

double d = 3.9;
// int i{d};                        // error: narrowing conversion
int i = static_cast<int>(d);        // 3

How to diagnose

  1. Types — Source and target types in the message?
  2. Constant — Is the value a compile-time constant that fits?
  3. Intent — Is truncation really wanted?

🔧 Still not fixed?

Many errors look alike. If the steps above didn’t solve it, one of these is probably what you’re facing:

Where this error sits

Origin: Application & API. Errors that are often confused with or caused by this one (click to open):

call of overloaded is ambiguous — C++: error: call of overloaded 'f(int)' is ambiguous (C/C++)call of overloaded is…comparison of integers of different signs — C/C++: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' [-Wsign-compare] (C/C++)comparison of integer…does not name a type — C++: error: 'string' does not name a type (C/C++)does not name a typeE0308 — Rust: error[E0308]: mismatched types — expected `X`, found `Y` (Rust)E0308invalid conversion from — C++: error: invalid conversion from 'const char*' to 'char*' [-fpermissive] (C/C++)invalid conversion fr…ISO C++ forbids comparison between pointer and integer — C++: error: ISO C++ forbids comparison between pointer and integer [-fpermissive] (C/C++)ISO C++ forbids compa…runtime error: — C/C++: runtime error: signed integer overflow / null pointer / shift exponent too large (UndefinedBehaviorSanitizer) (C/C++)runtime error:template argument deduction/substitution failed — C++: error: template argument deduction/substitution failed / couldn't deduce template parameter (C/C++)template argument ded…narrowing…

Explore the map of this error Full error map →

🧠 Still stuck? Analyze your error

Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.

💬 What worked for others

No tips yet — did something else fix this for you?

Share what worked for you

Tips are checked by an editor before they appear. Links are removed.