C++ Module 15
Build systems, testing and tooling interview questions
Interview questions on build systems, testing and tooling: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
What is the difference between PRIVATE, PUBLIC and INTERFACE in target_link_libraries?
Answered in the lesson CMake for C++: targets, properties and presets
-
Fresher
What is the difference between CTest and a test framework such as GoogleTest or Catch2?
Answered in the lesson Unit tests with GoogleTest or Catch2 and CTest
-
Fresher
Why is adding a third-party library harder in C++ than in a language with one package manager, and what do vcpkg and Conan do about it?
Answered in the lesson vcpkg and Conan: C++ dependency management
-
Fresher
Why do you compile with -O0 -g before stepping through a C++ program in a debugger?
-
Fresher to mid
Why do AddressSanitizer and ThreadSanitizer need separate builds?
Answered in the lesson Sanitizer and hardened C++ build presets
-
Fresher
What is the difference between clang-format, clang-tidy and a static analyzer such as clang --analyze?
Answered in the lesson clang-tidy, clang-format and static analysis
-
Fresher to mid
What is the difference between a sampling profiler and an instrumenting profiler?
Answered in the lesson Profiling C++: finding where the time goes
-
Fresher
Why does long have 4 bytes on Windows but 8 bytes on 64-bit Linux and macOS?
Answered in the lesson Portability across compilers, platforms and judges
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Fresher to mid
A CMake project builds on your laptop, but a teammate's fresh clone fails: the app cannot find mathx/stats.hpp, a header of the project's own mathx library. That library's CMakeLists.txt calls include_directories(include), and you once ran make install for mathx. Explain both results and fix the CMake code.
- What it tests
- Directory-scoped versus target-scoped settings, usage requirements, how an installed copy of a header hides a missing dependency, and making the build reproducible.
- First step
- Compare the app's compile command on both machines, from compile_commands.json or cmake --build --verbose. include_directories() reaches only targets in the library's own folder and the folders below it, so the app's command has no -I for mathx on either machine. Your laptop finds the header anyway, in /usr/local/include, where make install copied it.
- Follow-ups
-
- How do you make sure no machine can pass by accident again?
- Another project uses mathx through find_package. What has to change for that to work?
- Why does the app sometimes compile against a stale header on your laptop?
From the lesson CMake for C++: targets, properties and presets
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
You added -Wall -Werror to CMAKE_CXX_FLAGS at the top of your CMakeLists.txt. Now a third-party library pulled in with FetchContent fails to build with GCC 16, on warnings in its own code that you cannot fix. Why, and how do you keep strict warnings on your code only?
- What it tests
- Global versus target-scoped flags, how FetchContent and add_subdirectory inherit settings, SYSTEM include folders, and where build-wide policy such as -Werror belongs.
- First step
- CMAKE_CXX_FLAGS set at the top is used for every C++ file of that folder and of every folder added below it, and FetchContent_MakeAvailable adds the library with add_subdirectory, so its sources get -Werror too. Move the warnings onto your own targets, for example an INTERFACE target that each of them links PRIVATE, and leave the library's flags alone.
- Follow-ups
-
- The library's headers still trigger warnings inside your own files. What then?
- Where should -Werror live so that developers can still try things out locally?
- How do you check which flags one file was really compiled with?
From the lesson CMake for C++: targets, properties and presets
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
Your macOS program runs from the build folder, but the zip you send to testers fails at start with "Library not loaded: @rpath/libgeo.dylib" and "Reason: no LC_RPATH's found". Explain what happened, and fix the build for macOS and Linux without asking testers to set any variable.
- What it tests
- How programs record and find shared libraries, the build-folder rpath that CMake adds and install removes, relative rpaths, and why environment variables are no fix.
- First step
- Run otool -L on the zipped program to see what it needs, and otool -l to see the folders it searches for @rpath. Then run both commands on the same program in the build folder, where it works, and compare: the difference between the two programs is the cause.
- Follow-ups
-
- Why not tell testers to set DYLD_LIBRARY_PATH?
- The program also loads a plug-in that needs libgeo. Which rpath does the plug-in need?
- How would you test this in CI so that it cannot come back?
From the lesson Static and shared libraries in C++
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A bug-fix release of your shared library adds one field to a public struct. Programs built against the previous release, which nobody recompiled, now print wrong values but do not crash. Explain the mechanism, and how you would ship the change safely.
- What it tests
- Binary compatibility: layouts and calling conventions compiled into callers, which changes break the ABI, SOVERSION and so-names, and ways to change an interface without breaking it.
- First step
- The old programs were compiled with the old header, so they still assume the struct's old size and the old offsets of its fields. Compare the two versions of the public header, and ask what the unchanged programs read when the library hands them the new layout. No compiler or linker checks this for you.
- Follow-ups
-
- Which kinds of change are safe in a minor release?
- How would you have caught the break before releasing it?
- Why did it print wrong values instead of crashing, and would it on every platform?
From the lesson Static and shared libraries in C++
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A GoogleTest test passes on every developer's machine but fails about once in 50 CI runs. Using CTest and the framework's own options, how do you find out whether the test or the code under test is at fault?
- What it tests
- Reproducing flaky tests: repetition, parallel and shuffled runs, shared state between tests, ThreadSanitizer, and deciding between a fix and a quarantine.
- First step
- Reproduce it before guessing. Run that one test many times with ctest --repeat until-fail:200 -R and its name, then the whole suite in parallel and in random order, with ctest -j 8 and --gtest_shuffle. A failure that needs other tests running points at shared state; one that appears alone points at the test or the code itself.
- Follow-ups
-
- It fails only when the whole suite runs in parallel. What does that suggest?
- The test waits for a background thread with a sleep. What would you change?
- When is it acceptable to disable a flaky test, and how?
From the lesson Unit tests with GoogleTest or Catch2 and CTest
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
A C++ suite of about 3,000 GoogleTest tests in 300 files takes 14 minutes in CI, most of it in the build. How would you make it faster without testing less?
- What it tests
- Where test time goes, compile cost per test file, precompiled headers, unity builds and caches, splitting test programs, parallel ctest, and keeping slow tests out of every pull request.
- First step
- Measure first: split the CI time into configure, build and ctest, and read the slowest tests in ctest's output. If the build dominates, the cost is the heavy framework headers compiled into each of 300 files and the links of large test programs, so attack compilation; if the run dominates, look at serial execution and a few slow tests.
- Follow-ups
-
- Running ctest with -j made it slower. Why could that happen?
- Should every test file become its own executable?
- How do you keep slow integration tests from delaying every pull request?
From the lesson Unit tests with GoogleTest or Catch2 and CTest
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A function decides whether a cached file is stale by comparing its modification time with the current time. How do you unit-test it reliably, without sleeping and without depending on the real clock or disk?
- What it tests
- Designing code for tests: passing in the clock and the file system, fakes against mocks, gMock, and testing the boundary cases of time.
- First step
- Separate the decision from the effects. Let the function take the current time and the file's modification time as values, or a clock and a small file-system interface as parameters. Then each test passes fixed times and checks the boundaries, such as exactly at the expiry time, without touching the disk or waiting.
- Follow-ups
-
- When would you use gMock instead of a hand-written fake?
- How do you still check that the real file-system code works?
- What do you do with code that calls std::chrono::system_clock::now() deep inside?
From the lesson Unit tests with GoogleTest or Catch2 and CTest
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A release build pulled a newer version of a dependency than the one QA tested, and a bug appeared in production. Design the dependency policy that makes every build reproducible, with vcpkg or with Conan.
- What it tests
- Version resolution, baselines, version ranges, lockfiles and recipe revisions, deliberate upgrades, binary caches and the checks CI needs.
- First step
- Find what was not pinned. With vcpkg, a manifest without a committed builtin-baseline, or a baseline updated by a script, lets versions move; with Conan, a version range or an exact version without a lockfile lets a new version or recipe revision in. The fix is a pin that is committed with the code and used by every build.
- Follow-ups
-
- How do you upgrade dependencies without giving up reproducibility?
- The same version was used, but the binary differed. How can that happen?
- What should CI check so that this cannot happen again?
From the lesson vcpkg and Conan: C++ dependency management
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
Before a release, the legal team asks which licences your app's 40 C++ dependencies carry and what you owe for each. How do you answer quickly and reliably, and what would make you stop the release?
- What it tests
- Getting licence data from the package managers, judging how far declared licences can be trusted, obligations by licence family, NOTICE files and policy checks in CI.
- First step
- Produce the list from the build, not from memory: conan graph info with the release profile and lockfile, or the licences and SPDX files vcpkg installs. Then compare every entry with an allowlist, and set aside each one you cannot classify for a closer look.
- Follow-ups
-
- A dependency's licence field is empty or says "Proprietary". What do you do?
- How does linking statically or dynamically change your obligations?
- How would you keep this from becoming a one-off scramble before each release?
From the lesson vcpkg and Conan: C++ dependency management
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
A team of five ships a desktop app on Windows, macOS and Linux with about 15 dependencies. CI takes 25 minutes, mostly building those dependencies from source on every run. Which dependency approach do you choose, and why?
- What it tests
- Comparing vcpkg, Conan, FetchContent and vendoring on platforms, binaries and caching, reproducibility, upkeep for a small team, and measuring before deciding.
- First step
- Measure what the 25 minutes are: if the dependencies are rebuilt because nothing is cached, any tool with a binary cache fixes most of it. Then weigh the platforms and the team: three systems and 15 libraries call for a real package manager with a cache, not FetchContent or vendored copies that someone must update by hand.
- Follow-ups
-
- The team already uses FetchContent for everything. How would you migrate?
- How do you cache dependency builds in CI with each tool?
- When would you vendor a library anyway?
From the lesson vcpkg and Conan: C++ dependency management
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A crash dump comes from an -O2 build with debug information. In the crashing frame the debugger shows a loop index of 1, a pointer as optimised out, and a line in the middle of another function. Which of these do you trust, and how do you get reliable values without moving the whole build to -O0?
- What it tests
- How optimisation changes debug information (location lists, inlining, line tables) and which evidence in an optimised crash is a fact rather than the compiler's reconstruction.
- First step
- Separate facts from reconstructions. The faulting instruction, the registers and the return addresses of the backtrace are facts. Variable values and line numbers are what the debug information claims, and in optimised code that record can be partial or wrong. Start from the faulting instruction in the disassembly and check each printed value against the code that uses it.
- Follow-ups
-
- Why can the reported line belong to a different function?
- When would you debug an -O1 or -Og build instead of -O0?
- What can the build add so that the next dump says more?
From the lesson Debugging C++ with LLDB and GDB
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A long-lived Order object's status field sometimes turns into Cancelled, although no code path should do that. Nothing crashes, and an AddressSanitizer build is clean. How do you find the code that writes the field, and what limits do you run into?
- What it tests
- Watchpoints on an address, hardware watchpoint limits, conditions, objects that move, and why a sanitizer cannot see a wrong but valid write.
- First step
- Reproduce it once under the debugger, stop just after the object is constructed, and put a watchpoint on the field. Each stop then shows the old value, the new value and the code that wrote it, so the first change you did not expect points at the culprit.
- Follow-ups
-
- The object is copied into a container after construction. What happens to the watchpoint?
- The field is written 10,000 times correctly before the bad write. How do you skip those stops?
- Why did AddressSanitizer report nothing?
From the lesson Debugging C++ with LLDB and GDB
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A C++ service crashed overnight on a Linux server. You have a core file and the stripped release binary that was deployed. What do you need to get a backtrace with function names, lines and values, and what do you change so that the next crash is easy to debug?
- What it tests
- Separate debug information, build IDs, matching a binary to a core, the kernel's core settings, and a release process that keeps symbols without shipping them.
- First step
- Make sure the binary is exactly the build that crashed, then find the debug information of that same build. A stripped binary gives GDB addresses only. With the separate debug file produced from the same build, the same core shows function names, lines and many values, because the debug information describes those exact addresses.
- Follow-ups
-
- The service has 40 threads. Which commands show what each one was doing?
- The core file was never written. What do you check?
- How do you keep debug information without shipping it to every server?
From the lesson Debugging C++ with LLDB and GDB
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
Your team wants to ship a C++ service with standard library hardening, but the latency budget allows at most 3 % more CPU. A benchmark shows libc++'s fast mode costing 12 % in one hot loop and nothing measurable elsewhere. What do you ship, how do you measure it, and what do you change?
- What it tests
- Choosing a hardening level from measurements, reading a micro-benchmark against whole-service cost, and removing checks locally without turning hardening off.
- First step
- Measure the whole service, not the loop: run the release and the hardened presets under the same load and compare CPU per request and p99 latency. A loop that costs 12 % but takes 5 % of the service's time adds about 0.6 % in total, well inside the budget.
- Follow-ups
-
- The hot loop really is 40 % of the service's time. What do you change in that loop?
- How do you stop a later change from removing hardening by accident?
- Would you ship extensive mode instead of fast mode?
From the lesson Sanitizer and hardened C++ build presets
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
After an out-of-bounds crash in production, a teammate proposes shipping the AddressSanitizer build of the service from now on, "so that the next bug is caught". Evaluate the idea and propose what you would ship instead.
- What it tests
- The cost and design limits of sanitizers in production, the difference between finding bugs and hardening, and a realistic plan of builds for tests and for production.
- First step
- Put numbers on the cost first: Clang's documentation gives about 2× the time for ASan, with more memory as well. Then separate the two goals: finding bugs before release, and stopping them safely after release.
- Follow-ups
-
- What would ASan in production still miss?
- How do you get the crash information you lost by not shipping ASan?
- Is there any case where a sanitizer in production makes sense?
From the lesson Sanitizer and hardened C++ build presets
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
After the team moves to GCC 15, a debug build that worked for years aborts in a test with "Assertion '__n < this->size()' failed" inside std::vector. The release build still passes. Is the new compiler wrong, and what do you do?
- What it tests
- Reading a standard library assertion as a bug report, telling a new check from a new bug, and fixing the caller instead of silencing the check.
- First step
- Read the assertion as a bug report: operator[] was called with an index that is not less than size(). Then ask what changed with the compiler: a check that did not run before can expose a bug that was always there, and the release build passes only because nothing checks there.
- Follow-ups
-
- Why did the release build never crash?
- Someone suggests switching the new checks off to make the build green. What do you answer?
- How do you make sure the release build would catch the next one?
From the lesson Sanitizer and hardened C++ build presets
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
Your team turns on clang-tidy with every check and gets 2,300 findings on a 60,000-line code base. How do you roll it out without stopping work, and how do you decide which checks stay?
- What it tests
- Staging checks, separating bug-finding checks from taste, baselines and changed-files runs, automatic fixes, NOLINT discipline and making the chosen checks fail CI.
- First step
- Group the 2,300 findings by check name before deciding anything, and look at what each of the largest groups asks for. Then ask which checks would have caught bugs this team has actually shipped: those are the candidates for the first stage.
- Follow-ups
-
- How do you keep new code clean while the old findings are still there?
- A check's automatic fix changes behaviour in one place. What does that tell you?
- When is a NOLINT comment acceptable?
From the lesson clang-tidy, clang-format and static analysis
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
The clang-format check in CI keeps failing on files that developers formatted locally, and each fix produces new differences elsewhere. What is going on, and how do you set it up so that it never happens again?
- What it tests
- Making a formatter give the same result on every machine: versions, style files, editors, CI checks and formatting only the lines a change touches.
- First step
- Compare clang-format --version on a developer's machine, in the editor and in CI. Then format one failing file with each of them, using the same style file, and compare the outputs line by line before changing any setting.
- Follow-ups
-
- Why does the editor disagree even when the terminal does not?
- How do you move the whole team to a new version without a week of noisy diffs?
- Should CI reformat the code itself and commit the result?
From the lesson clang-tidy, clang-format and static analysis
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A colleague says a module is safe because clang-tidy and the static analyzer report nothing on it. What can those tools miss, and what would you add before trusting the module?
- What it tests
- Knowing the limits of static tools, telling an empty report from a well-covered module, and choosing the run-time tools and tests that cover the rest.
- First step
- Ask what the tools were able to see before trusting what they did not report: which checks ran, on which files, with which flags. A cheap test is to plant a known bug in the module and see whether each tool reports it.
- Follow-ups
-
- How can you tell how much of the code an analyzer really covered?
- Which bugs do sanitizers find that static analysis cannot?
- Which tests would you write first for such a module?
From the lesson clang-tidy, clang-format and static analysis
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Fresher to mid
You made a parsing function three times faster in a micro-benchmark, but the whole program became only 4 % faster. Explain the numbers, and describe how you should have chosen what to optimise.
- What it tests
- Amdahl's law with real numbers, the difference between a function's speed and its share of the run time, and a profile-first method.
- First step
- Work out the share. If a part takes a fraction p of the run time and becomes s times faster, the program takes 1 − p + p / s of its old time. With s = 3 the saving is 2p / 3, and a saving of 0.04 gives p = 0.06: the function was only 6 % of the run time.
- Follow-ups
-
- What is the most the program could gain if that function took no time at all?
- Which numbers from a profile would have told you this before you started?
- When is a 4 % gain still worth keeping?
From the lesson Profiling C++: finding where the time goes
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
After a release, a C++ service's p99 latency doubled, yet a CPU profile under the same load looks the same as before and CPU use did not rise. Why can a CPU profile miss the cause, and what do you measure instead?
- What it tests
- The difference between on-CPU and off-CPU time, what sampling profilers record, and tools for waiting time: locks, I/O and scheduling.
- First step
- A CPU profile only sees threads while they run. If requests got slower without more CPU work, they spend the extra time waiting: on a lock, on I/O, on another service or in a queue. Compare wall-clock time per request with CPU time per request; the gap is the waiting time to explain.
- Follow-ups
-
- How do you find which lock the threads wait on?
- Why does p99 move while the median stays the same?
- What would you add to the service so that the next regression is visible at once?
From the lesson Profiling C++: finding where the time goes
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
The top line of a perf report is memcpy, with 35 % self time, in a C++ program that never calls memcpy directly. What does that tell you, and how do you find the code to change?
- What it tests
- Reading self against total time, using callers in a call-graph report or flame graph, and the C++ habits that produce hidden copies.
- First step
- memcpy is where the bytes are copied, not why. Ask for its callers: perf report with call graphs (or a flame graph) shows which of your functions sit below memcpy in the stacks. Hidden copies usually come from objects passed or returned by value, strings built repeatedly, or vectors that grow without reserve.
- Follow-ups
-
- The callers show std::vector's push_back. What is happening?
- The stacks below memcpy are unnamed addresses. What do you change in the build?
- How do you prove that your fix removed the copies?
From the lesson Profiling C++: finding where the time goes
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
Your contest template uses <bits/stdc++.h>, __int128 to compute (a * b) % m for m up to 10^18, and long for 64-bit counts. You must now build it with MSVC on Windows and test it on a Mac. What breaks, and how do you port it without losing correctness?
- What it tests
- Recognising library headers, compiler extensions and data-model assumptions, and replacing each with a portable construct that keeps the arithmetic exact.
- First step
- List the assumptions, then test each on each target. The header exists only in libstdc++; __int128 exists only in GCC and Clang on 64-bit targets; long has 4 bytes on Windows. MSVC fails on the header first and on __int128 next, and Apple clang stops at the header too, so build on both before fixing anything.
- Follow-ups
-
- How do you multiply modulo 10^18 exactly without __int128?
- Is the long double shortcut for mulmod a portable fix?
- How do you keep the template convenient without <bits/stdc++.h>?
From the lesson Portability across compilers, platforms and judges
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A string hash function gives different values on an Arm64 Linux server than on x86 laptops and Macs, so cache keys stop matching. The code compiles without warnings on every machine. What is a likely cause, how do you prove it, and how do you fix it?
- What it tests
- The implementation-defined sign of plain char, how it changes arithmetic on bytes above 0x7F, reproducing a platform difference locally, and writing byte code that is the same everywhere.
- First step
- Look for arithmetic on plain char: hash functions often add or shift each char into the result. Plain char is signed on x86 and on Apple's arm64 platforms but unsigned on Arm64 Linux, so a byte such as 0xC3 of a UTF-8 text is -61 on one machine and 195 on the other. Hashes of pure ASCII text match; the others differ.
- Follow-ups
-
- How do you reproduce the server's behaviour on a laptop?
- Which warnings or tests would have caught it before the release?
- Some values were already stored with the old hashes. How do you migrate?
From the lesson Portability across compilers, platforms and judges
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
Your open-source C++ library promises to support GCC, Clang and MSVC on Linux, macOS and Windows, but each pull request may use about 30 minutes of CI time. Design the matrix: which jobs, with which flags, and what each one is there to catch.
- What it tests
- Choosing a small set of compiler and platform jobs that covers headers, extensions, data models, char signedness and library gaps, and spending the budget where failures are most likely.
- First step
- Start from what can differ, not from every combination: nine compiler and system pairs are too many for 30 minutes. List the standard libraries and data models the library promises, give each one a job that would fail on it, and only then add cheap variants for what those jobs cannot see.
- Follow-ups
-
- Which flags turn each job's warnings into failures?
- How do you test unsigned char without an Arm machine?
- Where do sanitizers fit in the same budget?
From the lesson Portability across compilers, platforms and judges
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes