Update: Using C++26 with contracts enabled

This commit is contained in:
David Gil de Gómez Pérez
2026-08-12 13:28:20 +03:00
parent 583f8d73db
commit 206742e9b3
2 changed files with 52 additions and 80 deletions
+1 -22
View File
@@ -8,19 +8,9 @@
"configurePresets": [ "configurePresets": [
{ {
"name": "default", "name": "default",
"displayName": "Default (system compiler)", "displayName": "GCC 16 + C++26",
"generator": "Unix Makefiles", "generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/build", "binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"COURSE_ENABLE_CONTRACTS": "ON"
}
},
{
"name": "gcc26-contracts",
"displayName": "GCC 16 + C++26 contracts (recommended)",
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/build-gcc26",
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug", "CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_COMPILER": "/opt/homebrew/bin/gcc-16", "CMAKE_C_COMPILER": "/opt/homebrew/bin/gcc-16",
@@ -33,10 +23,6 @@
{ {
"name": "default", "name": "default",
"configurePreset": "default" "configurePreset": "default"
},
{
"name": "gcc26-contracts",
"configurePreset": "gcc26-contracts"
} }
], ],
"testPresets": [ "testPresets": [
@@ -46,13 +32,6 @@
"output": { "output": {
"outputOnFailure": true "outputOnFailure": true
} }
},
{
"name": "gcc26-contracts",
"configurePreset": "gcc26-contracts",
"output": {
"outputOnFailure": true
}
} }
] ]
} }
+51 -58
View File
@@ -5,35 +5,30 @@ A hands-on C++ course with **56 Google Test exercises** organized into **14 modu
## Requirements ## Requirements
- **CMake** 3.20+ - **CMake** 3.20+
- **C++26-capable compiler** - **GCC 16+** with C++26 and contracts support
- **GCC 16+** recommended (required for `pre`/`post` contracts)
- Apple Clang can build most exercises but **does not support contracts yet**
- **CLion** (recommended) or any CMake-aware IDE - **CLion** (recommended) or any CMake-aware IDE
- Internet access on first configure (Google Test is fetched automatically) - Internet access on first configure (Google Test is fetched automatically)
Install GCC 16 on macOS (Homebrew):
```bash
brew install gcc@16
```
## Quick Start (CLion) ## Quick Start (CLion)
1. Open this folder in CLion (`File → Open…`). 1. Open this folder in CLion (`File → Open…`).
2. Select the **`gcc26-contracts`** CMake profile (see `CMakePresets.json`). 2. Use the **`default`** CMake profile (`GCC 16 + C++26` from `CMakePresets.json`).
3. Reload CMake when prompted. 3. Set the toolchain to **GCC 16** (`/opt/homebrew/bin/g++-16`).
4. Pick an exercise target (e.g. `02_control_flow_loops`) in the run configuration dropdown. 4. **Disable Clang-based analysis** (this project targets GCC only):
5. Implement the TODOs in the matching `src/*.cpp` file. - **Settings → Languages & Frameworks → C/C++ → Clangd** → disable, **or**
6. Run the test target until all assertions pass. - **Settings → Editor → Inspections → C/C++ → General → Clang-Tidy** → disable
5. Reload CMake, pick an exercise target (e.g. `02_control_flow_loops`), implement TODOs, run tests.
## Quick Start (Terminal) ## Quick Start (Terminal)
**Recommended — GCC 16 with contracts:**
```bash ```bash
cmake --preset gcc26-contracts cmake --preset default
cmake --build build-gcc26
ctest --test-dir build-gcc26 --output-on-failure
```
**Default toolchain:**
```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build cmake --build build
ctest --test-dir build --output-on-failure ctest --test-dir build --output-on-failure
``` ```
@@ -41,8 +36,18 @@ ctest --test-dir build --output-on-failure
Run a single exercise: Run a single exercise:
```bash ```bash
cmake --build build-gcc26 --target 02_control_flow_loops cmake --build build --target 02_control_flow_loops
./build-gcc26/modules/02_control_flow/02_control_flow_loops ./build/modules/02_control_flow/02_control_flow_loops
```
Manual configure (without presets):
```bash
cmake -S . -B build \
-DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-16 \
-DCMAKE_C_COMPILER=/opt/homebrew/bin/gcc-16 \
-DCOURSE_ENABLE_CONTRACTS=ON
cmake --build build
``` ```
## Project Structure ## Project Structure
@@ -50,33 +55,22 @@ cmake --build build-gcc26 --target 02_control_flow_loops
``` ```
cppc/ cppc/
├── CMakeLists.txt # Root project + Google Test ├── CMakeLists.txt # Root project + Google Test
├── CMakePresets.json # GCC 16 + C++26 preset
├── cmake/ ├── cmake/
│ ├── CourseExercise.cmake # add_course_exercise() helper │ ├── CourseExercise.cmake # add_course_exercise() helper
│ ├── CourseOptions.cmake # Warnings, standards, contracts │ ├── CourseOptions.cmake # Warnings, standards, contracts
│ └── toolchains/gcc-16.cmake # Optional GCC 16 toolchain file │ └── toolchains/gcc-16.cmake # GCC 16 toolchain file
├── CMakePresets.json # CLion/CMake presets (gcc26-contracts) ├── support/ # Contract violation handler
├── support/ # Shared contract violation handler
└── modules/ └── modules/
├── 01_fundamentals/ # Types, operators, I/O ├── 01_fundamentals/
├── 02_control_flow/ # if, switch, loops ├── 02_control_flow/
── 03_functions/ # Functions and recursion ── ... # 14 modules total
├── 04_arrays_and_strings/ # Arrays, string, vector
├── 05_pointers_and_references/
├── 06_oop_basics/ # Classes, inheritance
├── 07_stl_containers/
├── 08_stl_algorithms/
├── 09_cpp11/ # C++11 features
├── 10_cpp14/
├── 11_cpp17/
├── 12_cpp20/ # Concepts, ranges, <=>
├── 13_cpp23/ # expected, mdspan, format
└── 14_cpp26/ # Frontier / C++26 direction
``` ```
Each module contains: Each module contains:
- `README.md` — learning goals and exercise list - `README.md` — learning goals and exercise list
- `include/` — function and class declarations (your contract) - `include/` — function and class declarations
- `src/`**your implementation** (start here) - `src/`**your implementation** (start here)
- `test/` — Google Test files (do not edit unless extending) - `test/` — Google Test files (do not edit unless extending)
@@ -113,49 +107,48 @@ Each module contains:
|--------|---------|-------------| |--------|---------|-------------|
| `COURSE_BUILD_TESTS` | ON | Build Google Test exercise targets | | `COURSE_BUILD_TESTS` | ON | Build Google Test exercise targets |
| `COURSE_WARNINGS_AS_ERRORS` | OFF | Treat warnings as errors | | `COURSE_WARNINGS_AS_ERRORS` | OFF | Treat warnings as errors |
| `COURSE_ENABLE_CONTRACTS` | ON | Enable `-fcontracts` on GCC 16+ targets | | `COURSE_ENABLE_CONTRACTS` | ON | Enable `-fcontracts` on GCC 16+ |
Example: Example:
```bash ```bash
cmake --preset gcc26-contracts -DCOURSE_WARNINGS_AS_ERRORS=ON cmake --preset default -DCOURSE_WARNINGS_AS_ERRORS=ON
``` ```
## C++26 Contracts ## C++26 Contracts
Exercises compile as **C++26**. On **GCC 16+**, the build enables: On GCC 16+, the build enables:
- `-fcontracts` - `-fcontracts`
- `-fcontract-semantic=enforce` - `-fcontract-evaluation-semantic=enforce`
- A shared `handle_contract_violation` handler in `support/contract_handler.cpp` - A shared `handle_contract_violation` handler in `support/contract_handler.cpp`
Use `#include <contracts>` and syntax like: Example:
```cpp ```cpp
auto factorial(int n) -> long long #include <contracts>
[[nodiscard]] auto factorial(const int n) -> long long pre(n >= 0);
```
```cpp
auto factorial(const int n) -> long long
pre(n >= 0) pre(n >= 0)
{ {
// ... // ...
} }
``` ```
**Apple Clang does not support contracts yet.** Use the `gcc26-contracts` preset in CLion or:
```bash
cmake -S . -B build-gcc26 \
-DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-16 \
-DCOURSE_ENABLE_CONTRACTS=ON
```
## CLion Tips ## CLion Tips
- Use **Run | Run…** and filter by module prefix (e.g. `12_cpp20`). - Use the **GCC 16** toolchain, not Apple Clang.
- Enable **Google Test** integration in CLion to see individual tests in the tree view. - Disable **Clangd** and **Clang-Tidy** inspections — they use the Clang frontend and do not support GCC C++26 contracts.
- Set breakpoints in your `src/` implementation while debugging failing tests. - Use CLions built-in **GCC** parser/inspections, or rely on compiler errors from the build.
- `compile_commands.json` is exported for clangd/clang-tidy if you use external tools. - Use **Run | Run…** and filter by module prefix (e.g. `02_control_flow`).
- Enable **Google Test** integration to see individual tests in the tree view.
## Notes on C++26 ## Notes on C++26
All exercises now build with **C++26**. Module READMEs still describe the language feature each exercise teaches (C++11, C++17, etc.), but the toolchain baseline is unified at C++26 for a consistent modern environment. All exercises build with **C++26**. Module READMEs describe the language feature each exercise teaches (C++11, C++17, etc.), but the toolchain baseline is C++26 throughout.
Happy learning! Happy learning!