In C and C++, sign qualifiers determine whether a variable can store both positive and negative values (signed) or only non-negative values (unsigned). These qualifiers are mainly used with integer types and influence the range of values a variable can hold.
Purpose of Sign Qualifiers
Control the range of values a variable can hold.
Optimize memory for use cases that don’t require negative values.
Help prevent bugs related to signed/unsigned mismatches (e.g., in loops, indexing, or comparisons).
1. signed
Qualifier
The signed
qualifier indicates that a variable can hold both positive and negative values. In most systems, integers are signed by default, meaning that a variable of type int
can store values in a range that includes both negative and positive numbers.
How It Works:
- The
most significant bit (MSB)
is reserved for thesign
.0
= Positive1
= Negative
- As 1 bit is reserved it reduces the maximum value range.
Typical Sizes and Ranges:
Type | Size (bits) | Range |
---|---|---|
signed int | 32 | -2,147,483,648 to 2,147,483,647 |
signed short | 16 | -32,768 to 32,767 |
signed char | 8 | -128 to 127 |
On most systems: int
, short
, and char
are implicitly signed unless specified otherwise.
Example:
signed int a = -10; // Stores negative value
signed short b = 32767; // Max positive value for signed short
int c = -100; // Same as signed int
By default, if you just write int
or short
, the system assumes signed
unless explicitly specified otherwise.
2. unsigned
Qualifier
The unsigned
qualifier restricts a variable to hold only non-negative (positive or zero) values. Since there’s no need to reserve a bit for the sign, the total number of positive values that can be stored increases, effectively doubling the maximum positive range.
Typical Sizes and Ranges:
Type | Size (bits) | Range |
---|---|---|
unsigned int | 32 | 0 to 4,294,967,295 |
unsigned short | 16 | 0 to 65,535 |
unsigned char | 8 | 0 to 255 |
Example:
unsigned int count = 5000; // Only non-negative values
unsigned short maxScore = 65535; // Max value for unsigned short
Using unsigned
is helpful when you know that your variable will only hold non-negative values, such as array indices, file sizes, or object counts. It ensures that the variable never goes below zero, making errors easier to catch.
⚠️ Note:
Assigning a negative value to an unsigned variable results in underflow, often wrapping to a large number:
Comparison: signed
vs unsigned
Feature | signed | unsigned |
---|---|---|
Supports Negatives | ✅ Yes | ❌ No |
Max Positive Value | Medium (due to sign bit) | Higher (no sign bit) |
Use Case | General-purpose integers | Counts, indices, memory sizes |
Default | Yes (e.g., int is signed int ) | No (must use unsigned keyword) |
🎯 When to Use Which?
Use signed
when:
You need both positive and negative values (e.g., balance, temperature, deltas).
You’re working with arithmetic that could go below zero.
Use unsigned
when:
You are certain the value will never be negative (e.g., array index, buffer size, loop counter).
You want extra range for positive values.
Pro Tip: Avoid Mixing Signed and Unsigned
Mixed comparisons or arithmetic between signed
and unsigned
can result in unexpected bugs or compiler warnings:
int x = -1;
unsigned int y = 1;
if (x < y) // May give unexpected result due to implicit conversion
✅ Best Practice: Ensure that both operands in comparisons or expressions use the same signedness.