It's worth mentioning that either way the CPU will end up either copying constant data from somewhere onto writable memory, or initializing writable memory in a loop. Just use std::fill() if the value is non-zero.
There would be a run-time overhead if and only if the constexpr function is not evaluated at compile-time (its argument is not a constant expression) or if the constexpr result is copied into a non-constexpr variable.
There will also be a runtime cost if you use the compile-time-evaluated array to initialize a variable array, which I believe is what OP is doing. And that's what I mean; you can't avoid that cost.
It should be noted that foo() returns an int, not an array.
Using constexpr gives better guarantees but it is possible that the compiler might be able to optimize the code even without it: https://godbolt.org/z/qohG186eY