We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Values, Types, Initialisation step 2 of 4
Handle signed counts and unsigned sizes
A container length and a requested count can use different integer types. Before subtracting or comparing them, check which type the expression uses.
A negative integer can become a large unsigned value
For std::vector<int> in this environment, size() returns an unsigned size type corresponding to std::size_t. With the usual 64-bit size_t and 32-bit int, the comparison below converts i to the unsigned type:
int i = -1;
bool inside = i < xs.size(); // false: converted -1 is the largest size_t
This does not test whether i is a valid index. In this example, -1 becomes 2^64 - 1, so it is not less than any size_t value. More generally, C++ first promotes integer operands, then selects a common type using their ranks and representable ranges. The result is not always unsigned just because one original operand was unsigned.
A loop with int i = 0; i < xs.size(); ++i can work for small containers.
The mixed types make it harder to reason about, and int cannot count through
a container larger than its range without signed overflow.
Subtraction has a different trap
On this platform, subtracting 1 from an unsigned size of zero wraps to the largest size_t value:
for (std::size_t i = 0; i <= xs.size() - 1; ++i) {
// xs[i] would already be out of bounds at i == 0 if xs is empty.
}
Use i < xs.size() for forward iteration. When no index is needed, a range-for
avoids this size calculation entirely. For reverse iteration, use reverse
iterators or a loop whose condition handles zero before decrementing.
An unsigned index alone does not make subtraction safe.
C++20's std::ssize(xs), available from <iterator>, provides a signed length.
It can simplify arithmetic that needs negative results, provided the length
and intermediate calculations fit the signed type. It does not check for
overflow or validate an index.
Your task
std::vector<int> last_n(const std::vector<int>& xs, int n);
Return a new vector containing the last n elements in their original order. Leave xs unchanged:
| Input xs | n | Result |
|---|---|---|
| [1, 2, 3, 4, 5] | 2 | [4, 5] |
| [1, 2] | 5 | [1, 2] |
| [1, 2] | 0 or a negative value | [] |
| [] | any supported n | [] |
When n is at least the length, return all elements. Handle n <= 0 before subtracting. Test values and n fit int, and vector lengths fit std::int64_t.
In the starter, xs.size() - n converts n to the unsigned size type before
subtracting. With two elements and n = 5, start wraps to a large value. The
following i < xs.size() condition is false immediately, so the function
incorrectly returns an empty vector. It does not read past the end in that case.
Check the boundary cases first, then compute a start index whose range you have established. Casting an unchecked result only changes its type; it does not fix the reasoning that produced it.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
C++ reference solution
Sign in to track your attempts toward unlocking the reference solution.