In C++17 mode, GCC is showing an unhelpful error message when diagnosing an incorrect constexpr function, but only if the size of the array in use exceeds 16. No error messages show up in C++20 or above. I saw this initially on 14.3.1 (eabi-unknown ARM), but it is the same with GCC 15.2 (x64). This may be a duplicate of 110401 and 113595 (I'm not sure), but I thought it was interesting that the error message is correct for arrays of size 16 or smaller. Compiler Explorer link: https://godbolt.org/z/rejbGeP9T #include <array> #include <cstddef> #include <cstdint> template <std::size_t N> constexpr std::array<std::byte, N> make_byte_array( const std::uint8_t (&a)[N]) { // Error on next line of code - uninitialized var in constant context std::array<std::byte, N> ret; for (std::size_t i = 0; i < N; ++i) ret[i] = std::byte{a[i]}; return ret; } int main() { // Correct error message for this line: // <source>:9:30: error: uninitialized variable 'ret' in 'constexpr' context // constexpr std::array<std::byte, 16> a = make_byte_array({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); // Once you go past 16, you get a bad and confusing error message: // <source>:10:5: error: 'goto' is not a constant expression constexpr std::array<std::byte, 17> a = make_byte_array({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}); return 0; }
Note: I'm not sure if leaving ret uninitialized is actually a constexpr violation to begin with, but since that is being enforced in C++17 mode, it would be nice to have a proper error message.
(In reply to Anthony Cozzolino from comment #1) > Note: I'm not sure if leaving ret uninitialized is actually a constexpr > violation to begin with, but since that is being enforced in C++17 mode, it > would be nice to have a proper error message. It is in C++17. C++20 has different rules with respect to uninitialized and constexpr.
On the trunk the reason is removed so it is even worse.
The fix for the code is simple though: std::array<std::byte, N> ret{}; That is value initialize ret. In C++17, uniniitialized variables are supposed to be rejected so this is accepts invalid for <=16 too. C++20 allows uninitialized variables to begin with as long as they are fully initialized at the end of the full constexpr expression.
Oh the goto part is a dup. *** This bug has been marked as a duplicate of bug 110401 ***