Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Integer promotion is the implicit conversion of integer types with a conversion rank lower than int to either int or unsigned int before an operation is performed on them. This mechanism ensures that arithmetic and bitwise operations are executed at the CPU’s natural word size, aligning with the C standard’s execution model.

The Value Preservation Rule

The C standard dictates how these smaller types are promoted based on a concept called value preservation (C11 Standard, Section 6.3.1.1):
  1. If an int can represent all possible values of the original type, the value is promoted to int.
  2. If an int cannot represent all possible values of the original type, the value is promoted to unsigned int.
Because a standard int is typically 32 bits and types like char (8 bits) and short (16 bits) are smaller, they almost universally promote to a signed int, regardless of whether the original type was signed or unsigned.

Affected Types

Integer promotion applies specifically to types with an integer conversion rank lesser than the rank of int:
  • char, signed char, unsigned char
  • short, unsigned short
  • _Bool (a fundamental unsigned integer type)
  • Integer bit-fields
  • Enumeration types (enum)

Triggering Contexts

Promotion occurs automatically when the affected types are used as:
  • Operands of unary operators: +, -, ~
  • Operands of binary operators: Arithmetic (+, -, *, /, %), bitwise (&, |, ^, <<, >>), and relational (==, !=, <, >, <=, >=).
  • Arguments to variadic functions: When passed to functions with a variable number of arguments (e.g., ...), smaller integer types undergo default argument promotions.
  • Controlling expression of a switch statement: The integer expression evaluated to determine the execution path explicitly undergoes integer promotion.

Syntax and Behavior Visualization

The following compilable program demonstrates how the type of an expression changes due to integer promotion, evaluated using the sizeof operator, and how promotion alters the behavior of bitwise operations on small unsigned types.
#include <stdio.h>
#include <stddef.h>

int main(void) {
    char a = 10;
    char b = 20;

    // 'a' and 'b' are individually promoted to 'int' before the addition.
    // The resulting expression yields an 'int'.
    size_t size_of_result = sizeof(a + b); 
    
    printf("sizeof(char): %zu byte(s)\n", sizeof(char));
    printf("sizeof(a + b): %zu bytes\n\n", size_of_result);
    // Output demonstrates size_of_result == sizeof(int) (typically 4), NOT sizeof(char) (1).

    unsigned char c = 0xAA; // 1010 1010 in binary

    // 1. 'c' is promoted to int: 0x000000AA (assuming 32-bit int)
    // 2. Bitwise NOT (~) is applied to the 32-bit int.
    // 3. The result is 0xFFFFFF55, NOT 0x55.
    int result = ~c; 

    // To restrict the result back to the original type width, 
    // an explicit cast is required after the operation.
    unsigned char truncated_result = (unsigned char)(~c); // Yields 0x55

    printf("Original c:   0x%X\n", c);
    printf("Promoted ~c:  0x%X\n", (unsigned int)result);
    printf("Truncated ~c: 0x%X\n", truncated_result);

    return 0;
}
Expected Output:
sizeof(char): 1 byte(s)
sizeof(a + b): 4 bytes

Original c:   0xAA
Promoted ~c:  0xFFFFFF55
Truncated ~c: 0x55

Distinction from Usual Arithmetic Conversions

Integer promotion is the first step in evaluating expressions. It strictly handles types smaller than int. If an expression involves types equal to or larger than int (e.g., int and long, or int and float), a separate mechanism called the usual arithmetic conversions takes over to find a common type after integer promotions have already been applied to any smaller operands.
Master C with Deep Grasping Methodology!Learn More