Jason Merrill wrote: > On 09/16/2014 06:23 AM, Ulrich Weigand wrote: > > Now in this case, we cast a pointer to the array to a pointer to a base > > type of the array element type -- but the intent is for the pointer to still > > refer to the whole array. (Of course, this only works if the base type > > is actually the same size as the array type.) > > And I'm arguing that this intent is not well expressed by the code. :) > > If they want to refer to the whole array, why are they casting the > pointer to a different type? And why are they passing the "subobject > only" value as the second argument?
It looks more reasonable in the original source :-) What we have there is a definition of struct Pollfd that wraps the standard header file type struct pollfd and adds a couple of helpers (like constructors that set up the struct in some standard ways etc.). Subsequent source code simply uses struct Pollfd wherever struct pollfd would otherwise be used. In particular, this occurs in a call to the system "poll" routine: struct Pollfd myfd[10]; [...] poll(myfd, count, 0); // 1 < count < 10 Now, that routine comes from glibc header files, and if _FORTIFY_SOURCE is defined, it becomes an inline function that resolves after inlining and constant folding in this instance to something like: __poll_chk ((struct pollfd *)myfd, count, 0, __builtin_object_size ((struct pollfd *)myfd, 1)); The __poll_chk routine then performs a runtime check that the value of "count" is within range of the object size passed in as fourth argument. Note that the cast is actually implicit, it simply occurs because the parameter of the inlined "poll" function is "struct pollfd *", but the caller passes in a "struct Pollfd *". The "subobject only" value comes from glibc headers, where they use it deliberately: poll is supposed to get an array of pollfd structures, and it is OK to access those; but if that array is embedded within a larger structure, we want to avoid overruns into the rest of the structure. Is this "wrapping" of system types in a derived calls supposed to work? If there is a better way to express this without breaking glibc headers, I'd be happy to let the authors know ... > > Note that with a somewhat equivalent C construct: > > > > struct pollfd > > { > > int fd; > > short int events; > > short int revents; > > }; > > > > struct Pollfd > > { > > struct pollfd x; > > }; > > > > struct Pollfd myfd[10]; > > > > we still get an object size of 80 for either: > > > > __builtin_object_size ((struct pollfd *)myfd, 1); > > > > or even > > > > __builtin_object_size (&myfd->x, 1); > > That strikes me as a bug, especially the second one. Jakub, any thoughts on this? Thanks, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain ulrich.weig...@de.ibm.com