Unit 7.2 · about 4 h
43 / 324Integer representation, pointers, references and spans
Native interfaces pass addresses and counts rather than Python objects. A correct value in the wrong integer type or a pointer without its extent can cross that boundary unsafely.
- explain
- implement
You can now
- Explain integer widths, signed and unsigned conversions, and the difference between representation and overflow rules.
- Read pointer and reference code without losing the array bounds or the referent's lifetime.
- Implement a span-based operation with explicit bounds and empty-input tests.
Covers
- Integer representation, conversions and overflow
- Pointers, references, arrays and explicit spans
Study, in this order
5 steps
- Integer representation and data modelscppreference
Integral types: Standard integer types and Character types; Range of values; Data models
Depth · Skip floating-point tables and C++26 reflection. Use the C++20 rules.
- Integer promotions and conversionscppreference
Integral promotion and Numeric conversions: Integral conversions
- Pointer ArithmeticAlgoMaster C++
The Setup: What Pointer Arithmetic Means through The Rules: One Past the End and Undefined Behavior
- References BasicsAlgoMaster C++
What a Reference Is through References as Return Values; Common Mistakes
Depth · Use the local-reference and dangling-return examples. The named-local rule of thumb is not the full set of temporary-lifetime extension rules.
- `std::span`cppreference
Opening contract; Member functions: Element access, Observers and Subviews; Notes and Example
Depth · Use the C++20 interface.
span::atis C++26, so write an explicit bounds check for this unit.
Focus on
- C++20 requires two's-complement signed representation, but signed arithmetic overflow is still undefined. Unsigned arithmetic wraps modulo 2 to the type's bit width.
- Conversions and promotions happen before arithmetic and comparisons. Narrow unsigned operands can promote to
int, so inspect the expression type, not only the declared variable type. - Pointer arithmetic advances by elements within an array, including its one-past position. That position may be compared but not dereferenced.
- A reference aliases an object; assignment through it does not rebind it. A span carries a contiguous extent but neither owns storage nor checks
operator[]in C++20.
Reproduce closed-book
-std=c++20 -O0 -g, write a function taking std::span<int> that doubles its elements. int a[]{2,4,6} becomes {4,8,12}; an empty span performs no writes. Write a separate checked accessor that throws std::out_of_range when i >= size(), and test i == 3 on that array. Predict and check that numeric_limits<unsigned>::max() + 1u is zero and that int n = -1 compared as n < 1u is false. Do not execute signed overflow to infer a wraparound rule: its behavior is undefined and no particular output is guaranteed.Traps
- Replacing a pointer with a span does not extend the underlying array's lifetime.
- Treating
sizeof(pointer)as the number of bytes in the pointed-to array. - Checking for signed overflow after the overflowing expression has already been evaluated. Check the operands before arithmetic.
Practice
AlgoMaster Exercise: Pointer Arithmetic
Exercises 1 to 5: offsets, prefix and postfix movement, a one-past-end sum, two-pointer reversal and a three-reversal rotation over one-past-end ranges
Write the valid pointer range before each loop. Then port Exercise 3 to std::span with an explicit bounds check and an empty-input test.
Self-test
-
Does two's-complement representation guarantee signed wraparound in C++20?
No. Representation and arithmetic semantics are separate; signed arithmetic overflow remains undefined. -
Can a one-past pointer be used as an end sentinel? Can it be read through?
It can be compared with pointers into that array. It cannot be dereferenced. -
A function returns a span over a local array. Is its length enough to make it safe?
No. The local array dies on return, so the span dangles even though it retains the old extent. -
Why does
-1 < 1uevaluate to false?Theintoperand converts tounsigned intunder the usual arithmetic conversions.-1becomes the maximumunsigned intvalue.
Completion criterion
Stop when
Your span operation and checked accessor pass the boundary tests, and you can explain the conversions and lifetime of every pointer or reference they use.
Mark passed, then open 7.3 Only mark this when you can do it without notes.Leads to
- 7.3 Struct layout, alignment, strides and locality Turn element offsets into byte-address calculations.
- 7.4 Storage duration, RAII, smart pointers and move semantics Keep the storage behind each borrowed view alive.
Resources for this unit
- AlgoMaster C++ Use the sections on compilation, pointers and references, memory, RAII and smart pointers, copy and move, STL containers, templates, errors, concurrency and paired exercises. Skip competitive-programming breadth already covered in Algorithms.
- cppreference Consult language lifetime, object model, value categories, memory model, atomics, containers and iterator invalidation while reading or modifying code.
Also in this section
- C++ Core Guidelines Use the Philosophy, Interfaces, Resource management, Expressions, Containers and concurrency rule groups to review ownership and safety decisions in the native component.
- Clang AddressSanitizer and UndefinedBehaviorSanitizer Compile seeded memory defects with AddressSanitizer and UndefinedBehaviorSanitizer, preserve the reports, repair the root cause and keep regression tests.
- pybind11 documentation Follow First steps and NumPy support to expose one small native function with explicit shape, dtype, stride, ownership, GIL and exception behavior.
- CMake tutorial Use the introductory steps for targets, libraries, testing and install rules. Produce one clean debug build and one optimized build without copied one-off commands.
- Algorithmica - AoS and SoA Read the AoS and SoA experiment for a measured case where keeping each record together wins, the counterpart to a single-field scan.
- `ld.so`: dynamic linker/loader Read DESCRIPTION, Dynamic string tokens and
LD_DEBUGto distinguish link-time symbols from runtime shared-library discovery on Linux. - Memory Layout Transformations Read Overview and Topics through AOS Form and SOA Form for field-wise access and locality trade-offs. Skip Intel array-notation syntax and the LIBOR example.
- GDB manual: Backtraces Use section 8.2 for frame numbers,
bt,bt -fulland optimized-out arguments when inspecting a native failure.