- Diagram showing memory access - 1 Update
- Observable end padding in arrays - 9 Updates
- Optimiser Repressing Linker Error - 1 Update
raltbos@xs4all.nl (Richard Bos): Jun 29 09:58PM > @Bqv~~o?gx|\<wI!SXOV:^]q+sIjeyi(<H{K-KWm"x/t > a?<lk?hp?+xtTB,JdG\pU9O'vvFw=d(*7P?i4cW{AYYB > 1,DCxI8=kU:db\F;*r^9!6hpo,"0#Ja(XK&|+4G(X@N# You can't fool me. That's not Befunge. This is: "'.niagA kcaB d"v> v v$<v"r There an"< >$v >#| :,: |#< @>"o ,egnufeB'"^@ Richard |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 29 09:49PM +0100 Hi, I have been trying to prove to myself that, under the C++ standard, one-dimensional arrays may not have observable end padding. It is clear that the elements of an array must be contiguous, in the sense that for an array of T of more than one element, &T[1] must be the same as &T[0]+sizeof(T), and so on, but I have not yet managed to find a provision which unambiguously forbids array end padding. In other words I have not found a requirement that, for any type T, sizeof(T[sz]) must be the same as sizeof(T)*sz. Where you might care about this is in relation to matrices (and other multi-dimensional arrays), where the issue translates into the extent to which you are allowed to use pointer arithmetic to access individual elements in matrices instead of using the subscript operators. I have seen lots of code which assumes contiguity over the whole of a multi-dimensional array, and I am pretty certain this requirement exists, but can anyone point me to where I can find it? |
Vir Campestris <vir.campestris@invalid.invalid>: Jun 29 09:53PM +0100 On 29/06/2020 21:49, Chris Vine wrote: > I have seen lots of code which assumes contiguity over the whole of a > multi-dimensional array, and I am pretty certain this requirement > exists, but can anyone point me to where I can find it? I think if there was such a requirement every compiler I've ever used would disobey it. Just the way all the libraries pad malloc (etc) requests up to some suitable block size. If I have an on-stack int64_t, then an array char[5], then another int64_t I'd be astonished to find there wasn't a gap at the end of the array. Andy |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jun 29 01:55PM -0700 On 6/29/2020 1:49 PM, Chris Vine wrote: > I have seen lots of code which assumes contiguity over the whole of a > multi-dimensional array, and I am pretty certain this requirement > exists, but can anyone point me to where I can find it? Fwiw, I always liked using a one dimensional array, then partitioning it using some math. Think of representing a 2d plane in a 1d array. Using the array form of new seems to create an unseen header. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 29 10:04PM +0100 On Mon, 29 Jun 2020 21:53:16 +0100 > If I have an on-stack int64_t, then an array char[5], then another > int64_t I'd be astonished to find there wasn't a gap at the end of the > array. Yes, I formulated my question poorly, as that was not my point about "observable padding". My "observable" was in the context of multi-dimensional arrays and the size of component sub-arrays. I would bet that sizeof(char[5]) is indeed 5 with your compiler, and I would like to prove that that is required. Can you point me to something that says that, for any type T, sizeof(T[sz]) must be the same as sizeof(T)*sz? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 29 11:08PM +0200 On 29.06.2020 22:53, Vir Campestris wrote: >> exists, but can anyone point me to where I can find it? > I think if there was such a requirement every compiler I've ever used > would disobey it. Surely you mean the opposite? > If I have an on-stack int64_t, then an array char[5], then another > int64_t I'd be astonished to find there wasn't a gap at the end of the > array. That doesn't appear to be what Chris is talking about. As I see it he's talking about >> a requirement that, for any type T, sizeof(T[sz]) must be the same as >> sizeof(T)*sz In C++17 this is specified by §8.3.3/2, ❝When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of /n/ elements is /n/ times the size of an element.❞ ... where the ❝This implies❞ is normative text, not a note. - Alf |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 29 10:15PM +0100 On Mon, 29 Jun 2020 23:08:13 +0200 > the array. This implies that the size of an array of /n/ elements is /n/ > times the size of an element.❞ > ... where the ❝This implies❞ is normative text, not a note. That is indeed what I was looking for. Many thanks. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 29 02:18PM -0700 > If I have an on-stack int64_t, then an array char[5], then another > int64_t I'd be astonished to find there wasn't a gap at the end of the > array. The question isn't about padding between distinct objects. Given: int64_t a; char b[5]; int64_t c; the standard says nothing about the order in which they're allocated. For certain orders, some padding may be required to satisfy alignment requirements. But even if they're allocated in the order in which they're defined, any padding following b is not part of b; sizeof (b) will (presumably) be 5, and the following 3(?) bytes will not be part of any named object. (Or the compiler might allocate some other object in that space.) Every compiler I've seen has sizeof (b) == 5 (disclaimer: I haven't really tested this). The question is whether the standard requires this, or allows padding past 5 bytes to be *part of* the array object. In a very quick look at (a draft of) the C++17 standard, I haven't found an explicit requirement. Either such a requirement is there and I haven't found it (always possible), or the authors of the standard felt it was too obvious to state. (Or they intended to allow padding at the end of an array, but I personally don't think that's likely.) Note that we can't necessarily use multidimensional arrays to argue that padding is forbidden. Given: int arr[5][5] the expression arr[0][7] has undefined behavior; it's not necessarily equivalent to arr[1][2]. (Typical compilers may generate the same code for both expression, which is of course valid for undefined behavior.) However, arr[0][5] is a valid pointer value (dereferencing it has undefined behavior), so another way to state the question is whether (&arr[0][5] == &arr[1][0]) must be true. Again, it typically is, but that doesn't prove that the standard requires it. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 29 10:38PM +0100 On Mon, 29 Jun 2020 13:55:46 -0700 > Fwiw, I always liked using a one dimensional array, then partitioning it > using some math. Think of representing a 2d plane in a 1d array. > Using the array form of new seems to create an unseen header. Yes, when using languages in which arrays are boxed types where you are provided with what amounts to a pointer to garbage collected memory, and the element type in use is unboxed, such as an integer, then for multi-dimensional arrays you are almost driven to constructing a single array and layering arithmetic on the indices over it in order to secure contiguity and localization and so encourage vectorized instructions. Much as I appreciate garbage collection, this is the kind of low level stuff where C and C++ and their array syntax come out well. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 29 02:41PM -0700 "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes: [...] >> On 29/06/2020 21:49, Chris Vine wrote: [...] > the array. This implies that the size of an array of /n/ elements is > /n/ times the size of an element.❞ > ... where the ❝This implies❞ is normative text, not a note. Yes, I had somehow managed to miss that. I'm still curious *how* it implies it. The "This implies that ..." wording seems to indicate that it's a consequence of some normative requirement elsewhere in the standard. (Nevertheless, I accept that it's required.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 29 10:02PM +0200 On 29.06.2020 19:22, Paavo Helde wrote: > } > Now the Func() call gets officially discarded and Func can legally > remain undefined. Gah, where's the upvote button on this Usenet thing? - Alf |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment