Skip to content

← Orientation and the Gate step 1 of 3

Easy Primitives

A correct program that still fails

Read the starter. It compiles. It returns the right answer for every test case. Press Submit and it fails anyway.

That is not a bug in the grader. It is the entire reason this track exists.

Three signals, not one

A C++ submission here is graded on three things, and all three must pass:

  1. It compilesclang++ -O2 -std=c++20, or g++ if that is what your machine has.
  2. The tests pass — your function is called once per test case.
  3. clang-tidy is clean — on the lines you wrote.

Most languages stop at 2. C++ cannot afford to, and the reason is specific to this language rather than a matter of taste.

Why the third signal exists

Rust teaches itself. Write the wrong thing and the borrow checker refuses, so you cannot ship it without noticing. C++ has no such reflex. You can write 1998 C++ today — raw new, NULL, C casts, output parameters — and every compiler on earth will accept it, link it, and run it correctly.

So “it compiled and the tests passed” tells you almost nothing about whether the code is good. The compiler is not the arbiter of quality in C++; it is the arbiter of legality, and those are very different bars.

clang-tidy is the other half. The checks enabled here are the ones a reviewer would raise:

bugprone-*         things that are probably a mistake
clang-analyzer-*   leaks, null dereferences, undefined behaviour
modernize-*        you used the idiom from a previous decade
performance-*      this copies, and it did not have to

What is wrong with the starter

find_first returns NULL when there is no match. That is a C macro, usually 0, and it has been the wrong answer in C++ since 2011:

warning: use nullptr [modernize-use-nullptr]
    return NULL;
           ^~~~
           nullptr

NULL is an integer. nullptr is a pointer that cannot be anything else, which means it does not silently pick the int overload of a function, and it does not compare equal to 0 by accident. The fix is six characters and the habit is worth more than the six characters.

Note the shape of that diagnostic — file, line, column, the check that fired, the offending token, a caret, and the suggested replacement underneath. You will read a hundred of these. Problem 2 in this track is about nothing else.

Your task

const int* find_first(const std::vector<int>& xs, int target)

Return a pointer to the first element equal to target, or a null pointer if there is none. Fix the diagnostic. Do not change anything else — the logic is already right, which is the point being made.

What the harness does

You never write main. The harness calls your function and turns its result into JSON: the index of the element you pointed at, or -1 for null. That is why the tests can talk about a pointer at all.