Skip to content

16 Beginner The Hundred

The Vanishing Array Element

a shopping list that comes up short

#include <iostream>
#include <iterator>

int main() {
    const char* fruits[] = {
        "apple",
        "banana"
        "cherry",
        "date",
    };

    std::cout << "shopping list (" << std::size(fruits) << " items):\n";
    for (const char* f : fruits)
        std::cout << "  - " << f << '\n';
}

Run it. How many items are on the list?

Answer

Three — banana and cherry have fused into a single item, bananacherry.

Why

There is no comma after "banana", and adjacent string literals are glued into one literal at compile time — "banana" "cherry" is exactly the same as "bananacherry". So the array genuinely has three elements, and std::size is telling the truth. Concatenation exists so long strings can be split across lines ("usage: frob FILE\n" " -v verbose\n"), which is why the compiler can't call it an error. Switching to std::array or std::vector<std::string> doesn't help either: the literals merge before the initializer list is even considered. GCC 11.5 compiles this silently even with -Wall -Wextra; Clang catches it under -Wextrasuspicious concatenation of string literals in an array initialization (-Wstring-concatenation).

The fix

Restore the comma — and keep one element per line with a trailing comma on the last, so a formatter or a code review can spot the odd one out:

        "banana",
        "cherry",

Takeaway: adjacent string literals silently merge into one — in a list of strings, a missing comma doesn't fail to compile, it deletes an element.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry