Programming Fundamentals Using C++

Resources

Toolchain setup, the C++ standard contract, the glossary, the example program library, lab templates, and where to get help.

The C++ standard and compiler contract

Audience: everyone authoring content; quoted in every rubric.

1. Decision

This course teaches C++17 (ISO/IEC TS 21541:2017 era; formally ISO/IEC 14882:2017). All examples, solutions, and assessments target C++17 and must compile with:

g++ -std=c++17 -Wall -Wextra -pedantic

(equivalent flags for clang++/MSVC in TOOLCHAIN.md).

2. Why C++17 and not older or newer

ConsideredVerdictReason
C++98/03rejectedPre-dates beginners' laptops; idioms (e.g. std::auto_ptr) are obsolete and actively harmful
C++11strong candidateThe "modern baseline": auto, range-for, lambdas, nullptr, uniform initialization
C++14/17selected (C++17)Strict improvements over C++11 with no new beginner burden: structured bindings, if-with-initializer, std::string_view (deferred in teaching), fold expressions (not needed) — and it is the default on the toolchains students will install in 2026
C++20/23rejected for v1Concepts, modules, ranges are excellent but add cognitive load; a documented migration path is kept (§ 5)

C++17 is also the intersection point of the course's two goals: portable standard C++ (compiles everywhere with a modern default toolchain) and minimal beginner confusion (no legacy idioms, no pre-standard quirks).

3. The compile contract

  1. Every .cpp file compiles warning-free with the flags above.
  2. int main() returns int; no platform-specific entry points.
  3. No compiler extensions (-pedantic is part of the contract).
  4. Undefined behavior is banned, full stop; implementation-defined behavior (e.g. int size) must be flagged in a comment when relevant.
  5. The teaching subset below is authoritative: if a lecture uses a feature, the feature appears in § 4; if not, it must not appear.

4. Feature policy — what we teach, what we defer

4.1 Taught (in schedule order)

main, statements, comments · int, double, char, bool, const, brace initialization {} · operators & precedence · cin/cout and stream state · if/else, switch · while, do-while, for, range-for · functions, overloading, default arguments, references (T&, const T&) · scope/lifetime · C-style arrays (as memory model + "why vector exists"), std::vector, std::string · struct · pointers, new/delete (briefly, conceptually) · ifstream/ofstream · selected <algorithm> functions · enum class · introduction to classes (constructor, members) · recursion.

4.2 Explicitly deferred (with the week we mention them)

FeatureDeferred toWhy
auto for localsmentioned week 3, taught week 9Safe only after types are understood
Lambdasweek 14 (demo only)Needs algorithm context
std::string_viewnot taughtOwnership subtleties exceed beginner scope
Move semantics / rvalue refsnot taughtOOP course material
Templates (writing)not taughtUsing std::vector<T> is; writing isn't
Exceptionsweek 13 mention onlyStream checks cover error handling needs
Concurrencynot taughtFar beyond scope
Modulesnot taughtC++20; build complexity

4.3 Banned in course code (correctness/pedagogy)

using namespace std; in headers · system("pause") · conio.h · magic numbers without named constants · uninitialized variables · C-style casts · macros-as-constants.

5. Migration path (C++20/23)

The course is written so that a C++20 adopter can upgrade with:

  1. Replace flag -std=c++17 with -std=c++20 (no course code should break).
  2. Introduce designated initializers and std::span in weeks 9–12 (optional enrichment boxes in lecture notes).
  3. Adopt import std; only when institutional toolchains uniformly support it.

The roadmap tracks this as a non-goal for v1 — see CONTENT_ROADMAP.md § 5.

6. References (verified, no invented citations)

Toolchain setup

Audience: students (also used by instructors to prepare lab machines). Goal: from zero to a running C++17 program in under 30 minutes.

0. What you need

  1. A C++17 compiler (pick your OS below).
  2. An editor — we standardize on VS Code with the Microsoft C/C++ extension (any editor works; the course shows VS Code).

1. Windows

Two supported options; pick one.

  1. Install MSYS2 from <https://www.msys2.org/> following its steps 1–3.
  2. In the MSYS2 UCRT64 shell:
   pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
  1. Add C:\msys64\ucrt64\bin to your Windows Path (Settings → search "environment variables" → Path → New).
  2. Open a new PowerShell/VS Code window and verify:
   g++ --version

Option B — Visual Studio (Community)

  1. Install Visual Studio Community from <https://visualstudio.microsoft.com/>.
  2. In the installer, select the "Desktop development with C++" workload.
  3. Build with the x64 Native Tools Command Prompt:
   cl /std:c++17 /W4 /EHsc hello_world.cpp

MSVC flag mapping: /std:c++17 ↔ -std=c++17, /W4 ↔ -Wall -Wextra.

2. macOS

  1. Install the command-line tools (Terminal):
   xcode-select --install
  1. Verify:
   clang++ --version

Apple clang understands -std=c++17 directly.

3. Linux (Debian/Ubuntu example)

sudo apt update
sudo apt install -y build-essential gdb
g++ --version

(Fedora: sudo dnf install gcc-c++ gdb; Arch: sudo pacman -S gcc gdb.)

4. Editor: VS Code in 4 steps

  1. Install VS Code: <https://code.visualstudio.com/>.
  2. Install the C/C++ extension (publisher: Microsoft).
  3. Open your course folder (File → Open Folder).
  4. Create hello_world.cpp, press F5, choose C++ (GDB/LLDB) — the extension generates a build task. If you prefer the terminal:
   g++ -std=c++17 -Wall -Wextra -pedantic hello_world.cpp -o hello
   ./hello

5. Verify your setup (do this now)

g++ -std=c++17 -Wall -Wextra -pedantic hello_world.cpp -o hello
./hello

Expected output ends with something like Hello, world!. If any step fails, check the troubleshooting table below or bring the exact error text to office hours — that text is the first debugging skill the course teaches.

SymptomLikely causeFix
g++: command not foundPATH missing (Windows)Redo Option A step 3; open a NEW terminal
'cl' is not recognizedUsed plain terminal with VSUse the x64 Native Tools prompt
undefined reference to mainCompiled the wrong/no fileCompile the file that has main()
Program builds but window closes instantlySome IDEs close consoleRun from a terminal

6. Why the course standardizes the command line first

GUI build systems hide the three error classes the course teaches (compile/link/runtime). The one-line g++ command keeps cause and effect visible; IDE projects are introduced as convenience, never as a prerequisite.

7. Verify-a-compiler matrix (instructors)

OSDefault course compilerC++17 flag
Windowsg++ 13 (MSYS2 UCRT64)-std=c++17
Windows (alt)MSVC 19.x/std:c++17
macOSApple clang 15+-std=c++17
Linuxgcc 12+-std=c++17

All course code compiles warning-free on every row of this matrix (see the compile contract in CPP_STANDARD.md § 3).

Example program library

Every example compiles with the course contract. This table lists the full library; three complete programs are shown below.

FileTeaches
array_algorithms.cppthe six core array algorithms as functions — fill/print, sum/
array_basics.cpparray initialization forms, traversal discipline, contiguity of
buggy_off_by_one.cppSEEDED-BUG program for L12/L16 — students must find the three
conversion_demo.cppimplicit promotion, assignment conversion, static_cast, and
decisions_grade.cppif / else-if chain design in three versions — naive (buggy),
dynamic_memory_caution.cppnew/delete discipline, the three failure modes (leak, dangling,
file_read_write.cpptext file I/O — token reading, line reading, record round-trip,
first_class.cppfirst class — private data, constructors, validated mutator,
functions_refactor.cppthe flat gradebook program (before) and its decomposed version
grid_basics.cpp2-D array declaration, row/column indexing, row-major memory
hello_world.cppthe smallest complete C++ program — used in week 1 to introduce
io_age_check.cppprompt/read/echo a validated age — used in L04 to teach stream
loop_patterns.cppthe six named loop patterns from L10, each as a small labeled
loops_sum_digits.cppsentinel-controlled while loop and digit-sum via % and / —
matrix_ops.cpp2-D aggregations and operations — row totals, column totals,
overload_ref_demo.cppoverload resolution, a working swap via references, and the
passing_modes.cppthe three passing modes with printed evidence — scalar by value
pointer_basics.cppaddresses, & and *, nullptr discipline, and pointer arithmetic
precedence_demo.cppprecedence, associativity, integer vs floating-point division,
robust_pipeline.cpprobust input/file handling — the three error tiers, the
scope_lifetime_demo.cppblock scope, shadowing, the global-mutable bug, and a static
search_compare.cpplinear vs binary search with comparison counters, plus the
sorting_traced.cppselection sort and bubble sort with per-pass snapshots and
string_algorithms.cppper-character and word-level string algorithms — reverse,
string_processing.cpp<cctype> classification, std::string operations, substr/find
struct_records.cppstruct definition, brace initialization, member access (., ->),
struct_to_class.cppthe struct -> class refactor checklist applied to the same
switch_menu.cppswitch anatomy — grouped cases, default, and the same logic as
types_and_sizes.cppdemonstrate every built-in type, brace initialization, and the

Three complete examples

array_algorithms.cpp

the six core array algorithms as functions — fill/print, sum/

// purpose: the six core array algorithms as functions — fill/print, sum/
//          average, min/max with index, count-if, reverse-in-place, linear
//          search — used in L18 and re-used across Modules 12-14.
// build:   g++ -std=c++17 -Wall -Wextra -pedantic array_algorithms.cpp -o arralg

#include <iostream>

// Print the array in one line.  Read-only: const array parameter.
void print_array(const int a[], int n)
{
    for (int i{0}; i < n; ++i)
    {
        std::cout << a[i] << ' ';
    }
    std::cout << '\n';
}

// Sum of all elements (accumulator pattern).
int sum(const int a[], int n)
{
    int total{};
    for (int i{0}; i < n; ++i)
    {
        total += a[i];
    }
    return total;
}

// Minimum value AND its index (two outputs -> two int& parameters).
void min_with_index(const int a[], int n, int& min_value, int& min_index)
{
    min_value = a[0];
    min_index = 0;
    for (int i{1}; i < n; ++i)
    {
        if (a[i] < min_value)
        {
            min_value = a[i];
            min_index = i;
        }
    }
}

// Count elements satisfying a property shown here as "even".
int count_even(const int a[], int n)
{
    int count{};
    for (int i{0}; i < n; ++i)
    {
        if (a[i] % 2 == 0)
        {
            ++count;
        }
    }
    return count;
}

// Reverse IN PLACE: swap symmetric pairs (i, n-1-i).
void reverse_in_place(int a[], int n)
{
    for (int i{0}; i < n / 2; ++i)
    {
        int temp{a[i]};
        a[i] = a[n - 1 - i];
        a[n - 1 - i] = temp;
    }
}

// Linear search: index of first occurrence, or -1.
int linear_search(const int a[], int n, int key)
{
    for (int i{0}; i < n; ++i)
    {
        if (a[i] == key)
        {
            return i;
        }
    }
    return -1;
}

int main()
{
    const int N{6};
    int data[N]{12, 5, 8, 21, 4, 8};

    std::cout << "data            : ";
    print_array(data, N);

    std::cout << "sum             : " << sum(data, N) << '\n';
    std::cout << "average         : "
              << static_cast<double>(sum(data, N)) / N << '\n';

    int min_value{};
    int min_index{};
    min_with_index(data, N, min_value, min_index);
    std::cout << "min             : " << min_value << " at index "
              << min_index << '\n';

    std::cout << "even count      : " << count_even(data, N) << '\n';

    reverse_in_place(data, N);
    std::cout << "reversed        : ";
    print_array(data, N);

    std::cout << "search 21       : index "
              << linear_search(data, N, 21) << '\n';
    std::cout << "search 99       : index "
              << linear_search(data, N, 99) << " (-1 = not found)\n";

    return 0;
}

array_basics.cpp

array initialization forms, traversal discipline, contiguity of

// purpose: array initialization forms, traversal discipline, contiguity of
//          memory, and the out-of-bounds reality — used in L17.
// build:   g++ -std=c++17 -Wall -Wextra -pedantic array_basics.cpp -o arrbasic

#include <iostream>

int main()
{
    // --- Four initialization forms and their exact semantics ---
    int full[3] = {10, 20, 30};       // all three explicit
    int partial[3] = {10};            // rest are ZEROED: {10, 0, 0}
    int inferred[] = {1, 2, 3};       // size deduced: 3
    int zeroed[3]{};                  // all zero

    std::cout << "full     : " << full[0] << ' ' << full[1] << ' '
              << full[2] << '\n';
    std::cout << "partial  : " << partial[0] << ' ' << partial[1] << ' '
              << partial[2] << '\n';
    std::cout << "inferred : " << inferred[0] << ' ' << inferred[1] << ' '
              << inferred[2] << '\n';
    std::cout << "zeroed   : " << zeroed[0] << ' ' << zeroed[1] << ' '
              << zeroed[2] << '\n';

    // --- Traversal discipline: const size + i < N ---
    const int N{5};
    int scores[N]{72, 88, 95, 61, 79};

    for (int i{0}; i < N; ++i)        // valid indices: 0..N-1
    {
        std::cout << "scores[" << i << "] = " << scores[i] << '\n';
    }

    // --- Elements are writable through their index ---
    scores[2] = 100;                  // replace 95
    std::cout << "after fix, scores[2] = " << scores[2] << '\n';

    // --- Memory is contiguous: addresses step by sizeof(int) ---
    std::cout << "addresses (contiguous, 4-byte steps on this platform):\n";
    for (int i{0}; i < N; ++i)
    {
        std::cout << "  &scores[" << i << "] = " << &scores[i] << '\n';
    }
    // Note: address FORMAT is platform-specific (how it prints is not
    // standard C++; that a block is contiguous IS standard).

    // --- Out of bounds: NO compiler error, NO reliable runtime error ---
    // scores[5] = 1;   // legal-looking, UNDEFINED BEHAVIOR — do not run.
    // The discipline that replaces the missing check:
    //   const int N + for (i = 0; i < N; ++i) + never index by accident.

    return 0;
}

buggy_off_by_one.cpp

SEEDED-BUG program for L12/L16 — students must find the three

// purpose: SEEDED-BUG program for L12/L16 — students must find the three
//          bugs by trace table FIRST, then run to confirm.
// build:   g++ -std=c++17 -Wall -Wextra -pedantic buggy_off_by_one.cpp -o buggy
//
// NOTE: this file intentionally contains logic errors (not syntax errors),
// so it compiles clean but prints WRONG results. That is the lesson.

#include <iostream>

int main()
{
    // Bug 1 (off-by-one): intended to print 1..5, prints 0..4.
    // The loop runs i = 0,1,2,3,4 — five iterations, wrong values.
    std::cout << "Count 1 to 5: ";
    for (int i{0}; i < 5; ++i)
    {
        std::cout << i << ' ';          // BUG: starts at 0, should be 1..5
    }
    std::cout << '\n';

    // Bug 2 (wrong boundary): intended sum of 1..4 = 10, but the condition
    // uses < instead of <=, so it sums 1+2+3 = 6.
    int sum{};
    for (int i{1}; i < 4; ++i)          // BUG: i <= 4 was intended
    {
        sum += i;
    }
    std::cout << "Sum 1..4: " << sum << "   (expected 10)\n";

    // Bug 3 (inverted condition): intended to print only passing scores
    // (>= 60), but prints the failing ones.
    int scores[]{45, 72, 88, 59, 61};
    std::cout << "Passing scores: ";
    for (int i{0}; i < 5; ++i)
    {
        if (scores[i] < 60)             // BUG: < should be >=
        {
            std::cout << scores[i] << ' ';
        }
    }
    std::cout << '\n';

    return 0;
}
// Expected output after fixes:
//   Count 1 to 5: 1 2 3 4 5
//   Sum 1..4: 10
//   Passing scores: 72 88 61

Lab submission and debug-log templates

Every lab submission uses these two templates (linked from each lab manual).

Student: {name} · Login/ID: {id} · Date: {date}

1. Task summary

TaskFileStatus (done/partial)
Guided 1guided_1.cpp
Guided 2guided_2.cpp
Independent 1indep_1.cpp
Independent 2indep_2.cpp

2. Build log

Paste the exact compile command and its (empty) output:

g++ -std=c++17 -Wall -Wextra -pedantic indep_1.cpp -o indep_1

3. Test-evidence table

#InputExpected outputActual outputVerdict
1boundary:pass/fail
2normal:pass/fail
3normal:pass/fail
4invalid (from Lab 4):pass/fail
5own case:pass/fail

4. Debug log summary (Lab 4 onward)

One row per defect found during the session (full log in debug_log_template.md):

DefectStageSymptomCauseFix
1compile/link/runtime/logic

5. Reflection (3–5 sentences)

What was harder than expected, what would you do differently, what question is still open?

6. Pre-lab answers

Attach scan/photo of the § 5 answers (or type them here).

Student: {name} · ID: {id}

One block per defect. The grade pays for the diagnosis, not the fix.

Defect 1

  1. Reproduce: exact input/command that triggers it.
  2. Symptom: what happens (error text, wrong output, hang).
  3. Isolate: smallest input/code region that still shows it.
  4. Stage: compile / link / runtime / logic.
  5. Hypothesis: what you believed caused it.
  6. Test of hypothesis: what you changed/checked to confirm.
  7. Fix and verify: the change + the rerun that proves it fixed.

Defect 2

(same structure)


Reference: the five-step loop is taught in Lab 4 and used from that lab onward: reproduce → isolate → hypothesize → test → fix-and-verify.

Glossary

Beginner-language definitions, in first-use order. Terms are added as content is authored (../docs/CONTENT_ROADMAP.md); a term used in lecture notes must exist here.

Status legend: ✅ defined · ⏳ planned (term listed, definition pending).

Week 1 — Foundations

Week 2 — Types

Weeks 3–5 — I/O and control flow

Weeks 6–8 — Functions

Weeks 9–12 — Data

Weeks 13–15 — Files, library, craft

Getting help

The 30-minute rule: if one error resists you for 30 minutes, get help. Struggling is how you learn; silent struggling is how you fall behind.

1. Before you ask — the 5-minute self-check

  1. Read the error top-down. The first diagnostic is usually the real one; later lines are often echoes. Find the file and line number.
  2. Reproduce it. Run the exact command from ../docs/TOOLCHAIN.md § 5. Does it still fail?
  3. Check the last change. Undo the last edit mentally — did the error move?
  4. Explain it aloud (rubber-duck style): "This loop should sum 1..10, but total prints 555." Saying the expectation out loud finds logic bugs fast.
  5. Shrink the program. Comment out half; does the error remain? Binary search your own code.

2. Ask a good question (in office hours, lab, or the forum)

Include, in this order:

  1. What you expected to happen.
  2. What actually happened (paste the first error and the code near its line number).
  3. What you already tried (from § 1).

Asking this way is itself course outcome PF-A4 (../LEARNING_OUTCOMES.md).

3. Where to get help

ChannelBest for
Lectures — ask immediatelyconcept confusion
Labs — raise your handbuild/run errors, task checkpoints
Office hoursassignments, debugging strategy, grading questions
Class forum/mailing list (as set up by your instructor)quick environment questions

4. Integrity guardrails when asking online

Discussing ideas publicly is fine; posting assignment code or pasting submissions into external services is not (../COURSE_OVERVIEW.md § 4.2). The suggested classroom AI policy: assistants may explain errors; they may not write code you submit.

Programming Fundamentals Using C++ · C++17 · 16 weeksBack to top ↑