[C++] Fixed-size C-style arrays inside functions cannot be used in compile-time expressions?

This is a question to C++ experts to get your take on the following:

#include <string>

template<size_t N>
constexpr size_t arrayLength(const char (&arr)[N]) {
    static_assert(N == std::size(arr));
    return N;
}

int main() {
    static_assert(3 == arrayLength("HI")); // note: +1 for null terminator
    return 0;
}

This program fails to compile (see godbolt) on Clang and MSVC but succeeds on GCC.

The culprit is the static_assert(N == std::size(arr));. The standard is C++20 so I expect std::size() to be a constexpr function. The error on Clang is “static assertion expression is not an integral constant expression” which kind of suggests to me that std::size(arr), somehow, can not be evaluated at compile-time?

Is this a known thing from the C++ standard? I guess this may be due to some very special semantics of (put simply) “C-style arrays are glorified pointers” but maybe there’s more depth to it.

P.S.: Stumbled upon this originally by trying to propagate string literals to llvm::StringLiteral through a “function boundary” and failed by, seemingly, this.

This is Implement P2280R4 Using unknown pointers and references in constant expressions · Issue #63139 · llvm/llvm-project · GitHub

1 Like