https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99471
Bug ID: 99471 Summary: Allow conversion from array of unknown bound to actual known bound Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: wjwray at gmail dot com Target Milestone: --- P0388 "Permit conversions to arrays of unknown bound" in C++20 does not explicitly discuss conversion back from unknown bound to the actual bound of the referenced object. Discussion with Richard Smith suggests that it is (or should be) allowed to static_cast back to the known bound: int a[4]{1,2,3,4}; int (&r)[] = a; // P0388 conversion int (&b)[4] = r; // error: cannot bind reference of type // 'int (&)[4]' to 'int []' It is intended that this be allowed (c.f. also bug 93191 end discussion). However, it requires the compiler to trace the reference back to its object. Allowing this enables new non-templated array-accepting function apis: https://godbolt.org/z/1x4Tzs constexpr // marking constexpr gives better codegen int sum(int(&x)[]) // despite being not constant evaluated { auto& in = (int(&)[__builtin_object_size(x,0) / sizeof(int)])x; int acc = 0; for (int i : in) acc += i; return acc; } int main() { int a[]{1,2,3,4}; return sum(a); // returns 10 (1+2+3+4) } Here, __builtin_object_size requires optimization flags of -O1 or greater in order to chase back the referenced object and extract its size in bytes. However, it is not constant evaluated so the C-style cast is casting to VLA. If the size can indeed be extracted as an integral constant expression then the cast is a static_cast, or implicit conversion, as above. So, this 'bug' is two requests: 1. Allow static_cast from T(&)[] -> T(&)[N] where N is the actual size (or pointer T(*)[] -> T(*)[N]) 2. Provide a constant-evaluated builtin to extract the referenced object size (strengthen __builtin_object_size if possible) (Some sort of array_size builtin, as discussed for C, would be good here too.)