https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45840

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |redi at gcc dot gnu.org

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
For C++ I expected this to give a sensible answer:

size_t f(char (&s)[10]) { return __builtin_object_size(s, 0); }

It's true that you can explicitly cast a different type to char(&)[10] but any
attempt to access another type through that would (I think) be undefined.
Presumably __builtin_object_size is being used alongside some access ... if
not, who cares what it returns?

Obviously this example is contrived (the array size is known here) but it
matters for e.g.

std::istream& read(std::istream& in, char (&buf)[10])
{
  return in >> buf;
}

The operator>> in libstdc++ uses __builtin_object_size to avoid overflow here,
but it doesn't work because the size of char(&)[10] is not known.

If the function is called like read(std::cin, reinterpret_cast<char(&)[10]>(x))
then either x is a char array with at least 10 bytes (in which case it's
harmless to treat it as a smaller array) or it's not (in which case writing up
to 10 bytes to it is undefined anyway).

By extension, maybe this should give a known size too (but maybe this is a
separate enhancement request):

size_t f(char* s) { s[9] = '\0'; return __builtin_object_size(s, 0); }

If s[9] isn't valid, we already have UB. So in the absence of anything more
precise, 10 is a reasonable lower bound for the array size.

Reply via email to