Skip to content
C++ Better Explained
Go back
What Is size_t in C++? The Type for Sizes and Indexing

What Is size_t in C++? The Type for Sizes and Indexing

If you’ve ever written a loop over a vector and seen a warning about “comparison between signed and unsigned,” you’ve already bumped into size_t. It’s an unsigned integer type built specifically to represent sizes and indexes, and understanding it clears up a whole category of confusing warnings.


What size_t Actually Is

size_t is an unsigned integer type defined in headers like <cstddef>. “Unsigned” means it can only hold zero and positive numbers — never negatives. That makes sense, because the things it measures (the size of an array, the length of a string, an index into a container) are never negative.

It is the type returned by the sizeof operator:

#include <iostream>
using namespace std;

int main() {
    size_t s = sizeof(int);
    cout << "An int is " << s << " bytes\n";
    return 0;
}

It is also the type returned by the .size() member function of standard containers like vector, string, and map.


Why Not Just Use int?

Two reasons.

First, size. size_t is guaranteed to be big enough to represent the size of the largest object your system can create. A plain int is often only 4 bytes (max ~2.1 billion), which is not enough to index every element of a very large container on a 64-bit machine. size_t scales with the platform.

Second, matching the standard library. Since .size() already returns size_t, using it for your loop counters means no conversions and no warnings:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> nums = {10, 20, 30, 40};

    for (size_t i = 0; i < nums.size(); i++) {
        cout << "nums[" << i << "] = " << nums[i] << "\n";
    }
    return 0;
}

Because i and nums.size() are both size_t, the comparison is clean and the compiler stays quiet. This is efficient because you avoid the hidden signed-to-unsigned conversion that happens when you use int i instead.

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

The Classic size_t Trap

Because size_t is unsigned, subtracting past zero doesn’t give you a negative number — it wraps around to a gigantic value. This bites people who count backwards:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3};

    // BUG: when i is 0, i-- wraps to a huge number, not -1
    for (size_t i = v.size() - 1; i >= 0; i--) {
        cout << v[i] << " ";
    }
    // This loop never ends!
    return 0;
}

The condition i >= 0 is always true for an unsigned type, so the loop runs forever (and reads out of bounds). Two safe fixes:

// Option 1: loop with an offset so the counter stays positive
for (size_t i = v.size(); i > 0; i--) {
    cout << v[i - 1] << " ";
}

// Option 2 (C++11+): use a range-based loop and reverse iterators
for (auto it = v.rbegin(); it != v.rend(); ++it) {
    cout << *it << " ";
}

Mixing Signed and Unsigned

The other common surprise is comparing a size_t with a negative int:

int a = -1;
size_t b = 5;

if (a < b) {          // looks true...
    cout << "a is less\n";
} else {
    cout << "b is less\n";   // ...but THIS often prints
}

Before the comparison, -1 is converted to a size_t, which turns it into a massive positive number. The lesson: don’t mix signed and unsigned values in comparisons. Keep sizes and indexes as size_t and keep genuinely-can-be-negative values as int.


Quick Reference

QuestionAnswer
Signed or unsigned?Unsigned (never negative)
Where is it from?<cstddef> (and pulled in by many headers)
What returns it?sizeof, .size(), strlen, and more
When to use itSizes, lengths, and container indexes
Biggest gotchaWrap-around when counting below zero

The Takeaway

Use size_t whenever you’re dealing with the size of something or indexing into a container, and keep signed and unsigned values on separate sides of your logic. Do that and the “signed/unsigned mismatch” warnings — along with the infinite loops they hide — simply go away.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Share this post on:

Written by

Sahil Bora

Software Engineer. Author and creator of C++ Better Explained.


Previous Post
The Rule of Three in C++ Explained (with Examples)
Next Post
C++ String Concatenation: 5 Ways to Join Strings

Keep Learning