Question
Consider this program:
#include <stdio.h>
int main(void)
{
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof('a') = %zu\n", sizeof('a'));
}
When compiled as C, a typical result is:
sizeof(char) = 1
sizeof('a') = 4
When compiled as C++, a typical result is:
sizeof(char) = 1
sizeof('a') = 1
Why does sizeof('a') differ between C and C++? What is the size of a character in each language if char is one byte in both?
Short Answer
The difference is not about the size of the char type. It is about the type of the character literal 'a'. In C, an ordinary character literal has type int; in C++, it has type char. Therefore, sizeof('a') is usually sizeof(int) in C and exactly sizeof(char) in C++.
Concept
A character literal is a value written between single quotes, such as 'a', '?', or '\n'.
It is important not to confuse these two expressions:
char letter = 'a'; // `char` is a type used for the variable
sizeof('a'); // `'a'` is a character literal with language-specific type
In C, an ordinary character literal such as 'a' has type int.
/* C */
sizeof('a') == sizeof(int)
In C++, an ordinary character literal such as 'a' has type char.
// C++
sizeof('a') == sizeof(char)
That is why the same source text can produce different results when compiled as C and as C++.
Mental Model
Think of 'a' as a label on a package, not as the package itself.
- In C, the label
'a'is placed in anint-sized package. - In C++, the label
'a'is placed in achar-sized package.
The written text is identical, but each language assigns it a different type. sizeof measures the package type chosen by the language, not the visual number of characters between the quotes.
Syntax and Examples
Use sizeof to inspect the size of a type or expression.
sizeof(char) /* size of the char type */
sizeof(int) /* size of the int type */
sizeof('a') /* size of the type of the literal 'a' */
C example
#include <stdio.h>
int main(void)
{
printf("char: %zu\n", sizeof(char));
printf("int: %zu\n", sizeof(int));
printf("'a': %zu\n", sizeof('a'));
}
In C, 'a' has type int, so the final two sizes match:
char: 1
int: 4
'a': 4
C++ example
Step by Step Execution
Trace this C program:
#include <stdio.h>
int main(void)
{
int code = 'A';
printf("%d\n", code);
printf("%zu\n", sizeof('A'));
}
- The compiler reads
'A'. - In C, the literal
'A'has typeint. - Its numeric value corresponds to the execution character set's code for
A(commonly 65, but do not assume ASCII in fully portable C). - The assignment to
int codeneeds no conversion because the literal is already anint. sizeof('A')measures the literal's type, so it producessizeof(int).
Now consider the C++ version:
#include <cstdio>
{
code = ;
std::(, code);
std::(, ());
}
Real World Use Cases
This difference matters when code is shared between C and C++ or when code relies on exact types.
- Cross-language libraries: A header or macro used by both C and C++ should not assume that
'x'has the same type in both languages. - Generic macros: In C, macros using
_Genericcan select different behavior for'a'and acharvariable because the literal is anint. - Overloaded C++ functions: In C++, overload resolution can choose a
charoverload for'a'. - Binary and text protocols: Developers often store byte values in
unsigned charbuffers. They should explicitly convert when a specific byte type is required. - Portability checks:
sizeof(char)andCHAR_BITare the correct tools for learning about the platform's byte representation;sizeof('a')is not a measurement of character storage.
Real Codebase Usage
Developers usually treat character literals as values, then choose an explicit type when storage or API contracts matter.
Store a byte explicitly
unsigned char marker = (unsigned char)'M';
This is useful for byte buffers, file formats, and network data. The cast makes the intended destination type clear.
Validate a character range
int is_ascii_digit(char ch)
{
return ch >= '0' && ch <= '9';
}
The literals may have different types in C and C++, but the comparisons work because the operands are converted as required by each language.
Use int for character input results in C
int ch = getchar();
if (ch == EOF) {
/* No more input or an input error. */
} else if (ch == 'q') {
/* Handle q. */
}
getchar() returns int, not char, so it can represent every value plus the special value. This is one historical reason is common in C character-processing APIs.
Common Mistakes
Mistake: assuming 'a' is always a char
/* Incorrect assumption in C */
sizeof('a') == sizeof(char)
In C, 'a' is an int. Use a char variable when you need the size of the char type:
char ch = 'a';
printf("%zu\n", sizeof(ch));
Mistake: treating a byte as always 8 bits
/* Not fully portable */
if (sizeof(char) == 1) {
/* Assume char has 8 bits */
}
sizeof(char) is always 1, so this check says nothing about its bit width. Use CHAR_BIT:
Comparisons
| Expression or type | In C | In C++ | Key point |
|---|---|---|---|
char | A character type; sizeof(char) == 1 | A character type; sizeof(char) == 1 | Same size rule in both languages. |
'a' | Type int | Type char | This causes the sizeof difference. |
sizeof('a') | sizeof(int) | sizeof(char) | Often 4 in C and 1 in C++, but only the relationship is guaranteed. |
Cheat Sheet
-
sizeof(char)is always1in both C and C++. -
A C/C++ byte has
CHAR_BITbits, whereCHAR_BIT >= 8. -
In C, an ordinary literal such as
'a'has typeint. -
In C++, an ordinary literal such as
'a'has typechar. -
Therefore:
/* C */ sizeof('a') == sizeof(int)// C++ sizeof('a') == sizeof(char) -
sizeof('a')is not guaranteed to be 4 in C; it depends onsizeof(int). -
'a'is a character literal; is a string literal.
FAQ
Why is sizeof(char) always 1?
The languages define a byte as the amount of storage occupied by a char. Therefore, sizeof(char) must be 1 by definition.
Does sizeof(char) == 1 mean a char has 8 bits?
No. It means char occupies one language byte. Use CHAR_BIT to get the number of bits in that byte. It is at least 8.
Why are C character literals int values?
This is a historical C language design choice. It also fits C character APIs such as getchar(), which use int so they can represent both character values and EOF.
Is sizeof('a') always 4 in C?
No. In C it equals sizeof(int). Four is common, but the C standard does not require that size.
Is sizeof('a') always 1 in C++?
For an ordinary character literal such as 'a', yes: its type is char, and is always 1.
Mini Project
Description
Build a small diagnostic program that reports the sizes of character-related types and demonstrates the different type of an ordinary character literal in C and C++. This is useful when learning portability and when maintaining code that can be compiled in either language.
Goal
Print platform character information and identify whether 'A' behaves as an int literal (C) or a char literal (C++).
Requirements
Requirement 1
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
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.