Compiler warnings
C++ warning: comparison of integer expressions of different signedness
This warning means a comparison mixes a signed integer, such as int, with an unsigned integer type such as vector::size_type. In a vector loop, use std::size_t, a range-based loop, or validate before converting.
Find the two operand types
A vector’s size() returns an unsigned size type. Comparing it with int mixes signed and unsigned operands and GCC warns under -Wall -Wextra. Newer GCC wording says “comparison of integer expressions of different signedness”; older versions may say “comparison between signed and unsigned integer expressions.” At /W4 on x64, MSVC does not warn here because int is narrower than the 64-bit std::size_t. /Wall reports C4388 for this comparison, but /Wall is off by default. MSVC reports C4018 at /W4 when both operands have the same width, such as int and unsigned int.
Failing C++17 example
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{4, 7, 9};
for (int i = 0; i < values.size(); ++i) {
std::cout << values[i] << '\n';
}
return 0;
}
GCC diagnostic core:
warning: comparison of integer expressions of different signednessHere, the operands are an int index and the vector?s unsigned size type.
Fixed example
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{4, 7, 9};
for (std::size_t i = 0; i < values.size(); ++i) {
std::cout << values[i] << '\n';
}
return 0;
}
Expected output:
4 7 9
Stop an unsigned reverse loop
An unsigned index is always greater than or equal to zero. In this loop, i >= 0 remains true after decrement wraps the index, so the loop does not terminate and later accesses outside the vector. GCC warns with -Wall -Wextra.
Warning example
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{4, 7, 9};
for (std::size_t i = values.size() - 1; i >= 0; --i) {
std::cout << values[i] << '\n';
}
return 0;
}
GCC diagnostic core:
warning: comparison of unsigned expression in '>= 0' is always trueMSVC code: none. Do not run this case because the loop does not terminate.
Fixed example
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{4, 7, 9};
for (std::size_t i = values.size(); i-- > 0;) {
std::cout << values[i] << '\n';
}
return 0;
}
Expected output:
9 7 4
Know what the comparison does
When a negative int is compared with an unsigned value of a suitable rank, the negative value converts to unsigned. For example, -1 < values.size() is false when the conversion produces a large unsigned value. The comparison does not test whether -1 is a valid index. This conversion rule also affects equality and arithmetic, so inspect the operand types rather than guessing from their printed values.
Use the container size type
An indexed loop can declare std::size_t i = 0 and compare i < values.size(). Include
Avoid an index when you do not need one
A range-based for loop visits each existing element without comparing an index to size(). This is often the clearest choice when the loop only reads or updates every element. Use an indexed loop when position matters, such as comparing neighbors or writing into a second sequence. The simplest loop type depends on the operation, not on suppressing a compiler message.
Convert only after checking
Sometimes an API requires int. First verify that the size fits in int, then convert explicitly. When an input index is signed, reject values below zero before converting it to std::size_t, and then check that it is smaller than size(). A cast alone can silence the warning while preserving a bug. Keep the range check close to the conversion and access.
Exercise
Replace the signed index with a loop that safely visits every vector value.
Broken program
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{2, 5};
for (int i = 0; i < values.size(); ++i) std::cout << values[i] << '\n';
return 0;
}
Compiler diagnostic core:
warning: comparison of integer expressions of different signednessSample input: none.
Expected output after the fix:
2 5
Hint 1: Compare the index type with size() result type. Hint 2: A range-based for loop avoids the index.
Show one possible solution
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{2, 5};
for (int value : values) std::cout << value << '\n';
return 0;
}
Expected output:
2 5
Related guides
Keep learning with CppPath
Continue with the Loops lesson. The full lesson includes a quiz and a checked coding challenge with a free account.