Skip to content

C and C++ Course Curriculum ​

This course teaches C, modern C++, and the native-development toolchain to programmers already comfortable with Swift, Java, or C#. It moves quickly through familiar control flow and abstraction concepts, then develops the less familiar machinery: object lifetimes, undefined behavior, translation units, linking, ABIs, build graphs, dependency discovery, and cross-platform toolchains.

The learning format and editorial rules live in ARTICLE_GUIDE.md; declared baselines live in SUPPORT_MATRIX.md.

Part 1: Languages, implementations, and the path to a program ​

1. What C and C++ actually are ​

Separates the two ISO languages from implementations, standard libraries, operating-system APIs, and third-party libraries. Introduces hosted and freestanding implementations and establishes why shared syntax does not make C a subset of modern C++.

2. From source code to a running program ​

Follows preprocessing, compilation, assembly, linking, loading, and execution. Introduces translation units, headers, object files, symbols, executables, static libraries, shared libraries, and the difference between compile, link, load, and runtime failures.

3. Compilers and platform toolchains ​

Explains GCC, Clang/LLVM, Apple Clang, MSVC, clang-cl, and MinGW-w64; compiler drivers; target triples; standard libraries; ABIs; language-mode flags; diagnostics; and practical compiler selection.

4. Setting up a development environment ​

Compares Visual Studio, Xcode, CLion, VS Code, and terminal-first setups. Covers PATH, compiler discovery, SDKs, extensions, project settings, and a repeatable environment check.

Part 2: Everyday C ​

5. Values, declarations, expressions, and control flow ​

Covers declarations, scalar types, literals, operators, blocks, selection, loops, functions at first use, and the distinction between expressions and statements. Slows down for integer division, promotions, sequence rules, and side effects.

6. The C type system and conversions ​

Covers integer ranks, signedness, floating types, qualifiers, casts, implicit conversion, _Bool, size_t, fixed-width types, and the usual arithmetic conversions.

7. Pointers, arrays, and memory layout ​

Builds a precise model of addresses, pointer arithmetic, arrays, decay, multidimensional arrays, alignment, object representation, aliasing, and pointer validity.

8. Functions, headers, translation units, and linkage ​

Develops declarations versus definitions, prototypes, parameter passing, function pointers and stateful callback conventions, variadic functions, internal and external linkage, static, extern, include guards, preprocessing, _Generic, and stable header design.

9. Structs, unions, enumerations, and bit fields ​

Covers aggregate and compound-literal initialization, layout and padding, tagged unions, enum limitations, bit fields, flexible array members, and opaque-handle APIs.

10. Strings, bytes, and text encodings ​

Explains null-terminated byte strings, length-aware buffers, common library functions, formatting, parsing, character encodings, and safe boundary policies.

11. Dynamic memory and ownership conventions ​

Covers allocation, resizing, deallocation, ownership transfer, borrowing, cleanup paths, arenas, double frees, leaks, dangling pointers, and API documentation conventions.

12. The C standard library and operating-system boundaries ​

Maps headers and facilities for I/O, files, time, signals, nonlocal control transfer, locale, threads, and atomics, then separates ISO C from POSIX and Windows APIs.

13. Undefined, unspecified, and implementation-defined behavior ​

Explains the categories that make implementation freedom possible, with engineering policies for overflow, bounds, initialization, lifetime, aliasing, shifts, and diagnostics.

Part 3: Everyday modern C++ ​

14. C++ as its own language ​

Shows which C knowledge transfers and which habits should change. Establishes value semantics, deterministic cleanup, the standard library, stronger types, and the risks of treating C++ as C with classes.

15. Values, references, initialization, and const ​

Covers initialization forms, references, auto, const, named casts, constant evaluation, value categories at a useful level, copies, moves, and parameter-passing choices.

16. Classes, invariants, and special member functions ​

Covers class layout, access, constructors, destructors, copy/move operations, the rules of zero/three/five, operator overloading, comparisons, inheritance, virtual dispatch, and object slicing.

17. RAII, ownership, and smart pointers ​

Develops deterministic resource management, scopes, unique_ptr, shared_ptr, weak_ptr, non-owning views, lifetime hazards, and why raw pointers need not mean ownership.

18. Containers, iterators, algorithms, and ranges ​

Teaches standard containers by invalidation, complexity, and ownership; then connects iterators, algorithms, views, and C++20 ranges.

19. Templates, concepts, and generic programming ​

Covers function and class templates, deduction, instantiation, overload resolution, ADL, type traits, class template argument deduction, constraints, concepts, variadic templates, specialization, compile-time diagnostics, and source organization.

20. Errors, exceptions, optional values, and results ​

Compares exceptions, error_code, system_error, optional, variant, and expected-style results; covers result propagation, stack unwinding, exception safety, noexcept, and boundary translation.

21. Lambdas and callable design ​

Covers captures, closure lifetime, generic lambdas, function objects, std::function, callback ownership, and composing algorithms without hiding mutation.

22. Concurrency, atomics, and the memory model ​

Introduces threads, mutexes, condition variables, futures, cooperative stopping, atomics, happens-before, data races, and why volatile is not synchronization.

Part 4: Standards, compatibility, and portability ​

23. C versions in practice ​

Traces C89/C90, C99, C11, C17, and C23; identifies major language and library additions; explains conformance modes, GNU dialects, optional facilities, and gradual adoption.

24. C++ versions in practice ​

Traces C++98/03 through C++11, 14, 17, 20, and 23, with a forward-looking treatment of C++26 work. Covers feature-test macros, implementation support, migrations, and selecting a project baseline.

25. Portability, ABIs, and platform differences ​

Covers data models, endianness, object formats, name mangling, calling conventions, symbol visibility, runtime libraries, POSIX versus Windows, source versus binary compatibility, and cross-language C interfaces.

Part 5: Building programs ​

26. Manual builds that expose every layer ​

Builds programs, static libraries, and shared libraries with direct compiler, archiver, and linker-driver commands. Explains include paths, library paths, macros, dependency files, command ordering, inspection tools, and debug/release flags.

27. Make and incremental builds ​

Covers targets, prerequisites, recipes, variables, automatic variables, pattern rules, generated dependencies, parallel builds, phony targets, configurations, and Make's boundary as a low-level build graph.

28. Modern CMake ​

Covers configure/generate/build/test/install phases, targets, usage requirements, scopes, generators, presets, toolchain files, dependencies, install/export rules, and single- versus multi-config workflows.

29. Visual Studio and integrated build workflows ​

Explains solutions, projects, MSBuild, configurations, platforms, property pages, debugger integration, native versus CMake projects, and equivalent concepts in Xcode, CLion, and VS Code.

Part 6: Dependencies and library distribution ​

30. Why native package management is different ​

Explains source versus binary packages, headers and link artifacts, ABI compatibility, transitive usage requirements, system packages, vendoring, submodules, and reproducibility.

31. vcpkg, Conan, FetchContent, and pkg-config ​

Demonstrates manifest-mode vcpkg, Conan profiles and generators, CMake FetchContent, find_package, pkg-config, system managers, NuGet's niche, lockfiles, registries, and binary caches.

32. Designing and distributing libraries ​

Covers public headers, API/ABI design, static/shared choices, visibility, semantic versioning limits, CMake package configuration, installation layouts, exported targets, and consumer tests.

Part 7: Testing, diagnosis, and automation ​

33. Testing C and C++ ​

Covers lightweight C tests, CTest, GoogleTest, Catch2, doctest, test doubles, integration tests, deterministic resource tests, and testing installed artifacts.

34. Debugging with GDB, LLDB, and Visual Studio ​

Covers debug information, optimization effects, breakpoints, stepping, stack frames, threads, watches, core dumps, and debugger-specific interfaces built over common concepts.

35. Warnings, sanitizers, and static analysis ​

Covers warning policies, AddressSanitizer, UndefinedBehaviorSanitizer, ThreadSanitizer, MSVC diagnostics, Valgrind, clang-tidy, static analyzers, false positives, and CI integration.

36. Formatting, linting, and editor integration ​

Covers clang-format, EditorConfig, compilation databases, clangd, IntelliSense, include analysis, pre-commit checks, and keeping editor behavior aligned with the build.

37. Profiling and performance measurement ​

Covers benchmarks, optimization levels, sampling and instrumentation, platform profilers, allocation and cache behavior, compiler output inspection, and measurement discipline.

38. Cross-compilation, CI, and reproducible builds ​

Covers build/host/target systems, sysroots, CMake toolchain files, containers, CI matrices, compiler caches, artifacts, dependency caches, deterministic inputs, and release builds.

Part 8: Putting the system together ​

39. Project structure and architectural boundaries ​

Organizes applications and libraries around targets and dependency direction, separating public headers, private implementation, platform adapters, tests, tools, generated code, and build output.

40. Choosing a practical toolchain ​

Provides reasoned defaults for Windows applications, portable libraries, small Unix utilities, embedded systems, teaching projects, and large monorepos without pretending one stack fits all.

41. Case study: a portable library and CLI ​

Builds one modest C library, a modern C++ wrapper and CLI, tests, installation rules, dependency metadata, presets, diagnostics, and CI. The same artifacts are first built manually and then expressed as CMake targets.

42. Reading and modernizing an unfamiliar project ​

Develops a safe reconnaissance and modernization sequence: find entry points, identify the build graph and ABI boundaries, reproduce builds, enable diagnostics, add characterization tests, update standards deliberately, and replace ownership hazards incrementally.

Approximate pacing ​

PartReading and exploration
Ecosystem and execution model7–10 hours
Everyday C20–28 hours
Everyday modern C++24–34 hours
Standards and portability8–12 hours
Build systems and IDEs14–20 hours
Dependencies and distribution10–15 hours
Quality and automation14–20 hours
Integrated project work10–15 hours