Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #138077 > unrolled thread

Pointer conversion and alignment

Started byAnton Shepelev <anton.txt@gmail.com>
First post2018-11-17 14:38 +0300
Last post2018-11-19 14:33 -0800
Articles 20 on this page of 134 — 18 participants

Back to article view | Back to comp.lang.c


Contents

  Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-17 14:38 +0300
    Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-17 17:37 +0300
      Re: Pointer conversion and alignment Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-17 21:01 +0000
        Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 00:43 +0300
          Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 01:20 +0300
            Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-17 18:12 -0500
              Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 02:32 +0300
                Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-17 18:59 -0500
                  Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 12:40 +0300
          Re: Pointer conversion and alignment Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-18 02:14 +0000
            Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 13:23 +0300
              Re: Pointer conversion and alignment Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-18 11:28 +0000
                Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 15:31 +0300
                  Re: Pointer conversion and alignment Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-18 15:03 +0000
                    Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 23:00 +0300
        Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 00:49 +0300
    Re: Pointer conversion and alignment Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-11-17 06:52 -0800
      Re: Pointer conversion and alignment Ian Collins <ian-news@hotmail.com> - 2018-11-18 09:18 +1300
        Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-17 13:49 -0800
          Re: Pointer conversion and alignment Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-11-17 13:57 -0800
            Re: Pointer conversion and alignment Ian Collins <ian-news@hotmail.com> - 2018-11-18 11:08 +1300
              Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 01:13 +0300
                Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-17 18:37 -0800
          Re: Pointer conversion and alignment Philipp Klaus Krause <pkk@spth.de> - 2018-11-18 14:14 +0100
    Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-17 10:05 -0500
      Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 01:08 +0300
        Re: Pointer conversion and alignment "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-11-17 14:31 -0800
          Re: Pointer conversion and alignment "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-11-17 16:10 -0800
            Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-18 15:01 +0300
              Re: Pointer conversion and alignment James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-18 07:25 -0500
                Re: Pointer conversion and alignment "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-11-19 21:30 -0800
              Re: Pointer conversion and alignment "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-11-20 14:20 -0800
        Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-17 18:04 -0500
        Re: Pointer conversion and alignment Philipp Klaus Krause <pkk@spth.de> - 2018-11-18 14:18 +0100
        Re: Pointer conversion and alignment scott@slp53.sl.home (Scott Lurndal) - 2018-11-18 19:49 +0000
      Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-11-23 18:27 -0800
        Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-23 21:59 -0500
          Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-11-24 00:32 -0800
            Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-24 08:17 -0500
              Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-11-29 09:55 -0800
                Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-29 21:48 -0500
                  Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-05 04:14 -0800
                    Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-12-05 08:14 -0500
                      Re: Pointer conversion and alignment Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-12-05 05:29 -0800
                        Re: Pointer conversion and alignment David Brown <david.brown@hesbynett.no> - 2018-12-05 14:44 +0100
                        Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-12-05 21:58 -0500
                      Re: Pointer conversion and alignment Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-12-05 16:38 +0300
                      Re: Pointer conversion and alignment scott@slp53.sl.home (Scott Lurndal) - 2018-12-05 14:23 +0000
                      Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-12-05 14:35 -0800
                      Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-08 19:28 -0800
                        Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-12-09 08:18 -0500
                          Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-12-09 14:35 -0500
                            Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-12-09 14:04 -0800
                              Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-12-09 20:40 -0500
                                Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-17 07:18 -0800
                                  Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-12-17 12:35 -0800
                                    Re: Pointer conversion and alignment Tim Rentsch <txr@alumni.caltech.edu> - 2018-12-17 12:48 -0800
        Re: Pointer conversion and alignment "Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid> - 2018-11-24 18:33 -0800
    My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-19 02:26 +0300
      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-19 11:08 +0000
        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-19 15:37 +0300
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-19 15:39 +0300
            Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-19 15:07 +0000
              Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-19 22:24 +0300
                Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-19 12:33 -0800
                  Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-20 00:34 +0300
                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-19 14:38 -0800
                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-20 00:43 +0000
                        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-19 21:44 -0500
                        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jadill33@gmail.com - 2018-11-20 07:11 -0800
                          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] bart4858@gmail.com - 2018-11-20 10:02 -0800
                Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-19 22:20 +0000
                  Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-20 14:01 +0300
                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Melzzzzz <Melzzzzz@zzzzz.com> - 2018-11-20 11:07 +0000
                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-20 15:12 +0300
                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-20 08:15 -0500
                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-20 23:08 +0300
                        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-20 14:13 -0800
                          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-21 16:38 +0300
                            Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-21 09:05 -0500
                              Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-21 20:28 +0300
                                Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-21 12:58 -0800
                                  Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-22 01:47 +0300
                                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-21 15:50 -0800
                                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-24 19:37 +0300
                                Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-21 21:22 +0000
                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-21 01:15 +0000
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-19 15:06 +0000
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] mark.bluemel@gmail.com - 2018-11-19 08:05 -0800
            Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] scott@slp53.sl.home (Scott Lurndal) - 2018-11-19 16:49 +0000
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-19 10:35 -0800
            Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-20 00:45 +0300
              Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-19 14:24 -0800
                Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-20 15:05 +0300
                  Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-20 08:31 -0500
                  Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Richard Damon <Richard@Damon-Family.org> - 2018-11-20 20:02 -0500
                    Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-21 22:47 +0300
                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] jameskuyper@alumni.caltech.edu - 2018-11-21 13:08 -0800
                        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-22 00:31 +0300
                      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-21 21:36 +0000
        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-19 16:04 +0300
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-19 14:56 +0000
      Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-24 19:24 +0300
        Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-24 21:31 +0000
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-24 21:46 +0000
          Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-25 01:12 +0300
            Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-11-25 01:39 +0000
              Re: My dynamic arrays module [was:Re: Pointer conversion and alignment] Anton Shepelev <anton.txt@gmail.com> - 2018-11-25 14:19 +0300
    Re: Pointer conversion and alignment jadill33@gmail.com - 2018-11-19 08:44 -0800
      Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-20 00:02 +0300
        Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-19 13:51 -0800
          Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-20 01:08 +0300
            Re: Pointer conversion and alignment jameskuyper@alumni.caltech.edu - 2018-11-19 14:31 -0800
              Re: Pointer conversion and alignment Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-20 15:21 +0300
                Re: Pointer conversion and alignment James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-20 08:59 -0500
                  Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-20 11:06 -0800
                    Re: Pointer conversion and alignment jameskuyper@alumni.caltech.edu - 2018-11-20 12:43 -0800
                      Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-20 14:33 -0800
                        Re: Pointer conversion and alignment Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-21 14:33 +0300
                          Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-21 07:49 -0500
                            Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-21 12:42 -0800
                          Re: Pointer conversion and alignment James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-21 08:41 -0500
                  Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-25 15:06 +0300
                    Re: Pointer conversion and alignment James Kuyper <jameskuyper@alumni.caltech.edu> - 2018-11-25 10:47 -0500
                      Re: Pointer conversion and alignment Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-11-26 12:42 +0300
                        Re: Pointer conversion and alignment Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-11-26 03:07 -0800
                          Re: Pointer conversion and alignment Keith Thompson <kst-u@mib.org> - 2018-11-26 12:56 -0800
                            Re: Pointer conversion and alignment Richard Damon <Richard@Damon-Family.org> - 2018-11-26 18:17 -0500
                        Re: Pointer conversion and alignment jameskuyper@alumni.caltech.edu - 2018-11-26 09:06 -0800
                          Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-26 23:52 +0300
                            Re: Pointer conversion and alignment jameskuyper@alumni.caltech.edu - 2018-11-26 13:13 -0800
                              Re: Pointer conversion and alignment Anton Shepelev <anton.txt@gmail.com> - 2018-11-27 00:31 +0300
                                Re: Pointer conversion and alignment jameskuyper@alumni.caltech.edu - 2018-11-26 14:15 -0800
        Re: Pointer conversion and alignment jadill33@gmail.com - 2018-11-19 14:33 -0800

Page 4 of 7 — ← Prev page 1 2 3 [4] 5 6 7  Next page →


#138112 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-19 15:37 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181119153734.485dbb156e26d9843e8305f6@g{oogle}mail.com>
In reply to#138111
Ben Bacarisse to Anton Sheplev:

>Only the size element might be a problem -- the others are
>guaranteed to be aligned.  And below, I argue that all
>three should be of the same type anyway and hence they will
>all be aligned.

What problem can there be if I access all three through a
char*?  My only consideration about their alignment was that
of performance.  Is it the problem you refer to?

>Alignment might be an issue for the data, though.  From the
>point of view of portable access the optimal layout is
>
>  +----------+----------+----------+---+---     ------     --+
>  |  length  | capacity |   size   |...|    ...  data   ...  |
>  +----------+----------+----------+---+---     ------     --+
>                                     ^
>                                     | padding
>
>where a possibly zero-sized gap is left after the three
>equal-sized meta-data items so as to re-gain maximal
>alignment.

I hadn't thought of this.  Is it right that a pointer to int
cannot contain an arbitrary byte address and work correctly?
In other words, can I access an allocated object throught a
pointer to int from an arbitrary byte offset?

>The simplest way to achieve this in modern C define a
>struct for the header:
>
>  struct meta_data {
>      int         length;
>      int         capacity;
>      size_t      size;
>      max_align_t data[];
>  };

Do you propose to use this header for the calculation of
offsets or for the actual access to the array's data and
metadata?

>>What is the best type for the index: int, unsinged int,
>>size_t?
>
>I don't see why you've made these different.  On many
>implementations, size_t is 8 bytes and int is 4, but surely
>a vast number of small objects is as likely as a small
>number of vast ones, maybe even more so?
>
>As for the signed/unsigned question, I would usually favour
>unsigned (as size_t is already an unsigned type), but that
>is partly conditioned by having started out using C on
>16-bit machines where that extra factor of two was so much
>more important.
>
>I also like the fact that the prototype then documents the
>fact that negative values are erroneous.

Thanks for your opinion.  I used size_t because that is the
type returned by sizeof().  There will be little harm in
using a shorter type, and some profit in making the three
fields of the same type.

>[...]
>(I think something's got lost here.  I think dynarray.c
>starts with those three includes and there's a /* to be
>added also.)

Yes, my mistake.

>>union intalias
>>{  char cdata[sizeof(int)];
>>   int  idata;
>>};
>
>I don't see the point of this union.  The effective type of
>the allocated storage is determined by the first modifying
>access, so if you store an int at start, that will be the
>effective type of that part of the storage.

As far I as have understood, the effective type is
determined by the *last* non-character modyfying access,
which is why I have gone to great length to access metadata
exclusively through a char*.  I have found no other way to
access metadata without breaking the rules of aliasing.

>(Mind you, I've always found the effective types rules
>confusingly written so I may have got hold of the wrong end
>of the stick.)

Maybe someone would help us?

>>/* ------------ Macros to access the fields of a dynamic array: ------------- */
>>#define SHIFT(A,S)   (((char*)A) - (S))
>>#define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
>>#define ORIGIN(A)    SHIFT(A, OFFSET)
>>#define GETLEN(A)    getint (ORIGIN(A))
>>#define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
>>#define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
>>#define SETLEN(A,L)  setint (ORIGIN(A),(L))
>>#define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
>>#define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
>
>I'd simplify all this with a struct for the header.

I am sure the rules of aliasing allow it.

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138113 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-19 15:39 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181119153953.77b3fe0d95abe9e27f5aebda@g{oogle}mail.com>
In reply to#138112
I wrote:

>Ben Bacarisse to Anton Sheplev:
>
>>>/* ------------ Macros to access the fields of a dynamic array: ------------- */
>>>#define SHIFT(A,S)   (((char*)A) - (S))
>>>#define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
>>>#define ORIGIN(A)    SHIFT(A, OFFSET)
>>>#define GETLEN(A)    getint (ORIGIN(A))
>>>#define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
>>>#define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
>>>#define SETLEN(A,L)  setint (ORIGIN(A),(L))
>>>#define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
>>>#define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
>>
>>I'd simplify all this with a struct for the header.
>
>I am sure the rules of aliasing allow it.

I meant I am *not* sure.

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138117 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-19 15:07 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<87sgzxgl6u.fsf@bsb.me.uk>
In reply to#138113
Anton Shepelev <anton.txt@g{oogle}mail.com> writes:

> I wrote:
>
>>Ben Bacarisse to Anton Sheplev:
>>
>>>>/* ------------ Macros to access the fields of a dynamic array: ------------- */
>>>>#define SHIFT(A,S)   (((char*)A) - (S))
>>>>#define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
>>>>#define ORIGIN(A)    SHIFT(A, OFFSET)
>>>>#define GETLEN(A)    getint (ORIGIN(A))
>>>>#define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
>>>>#define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
>>>>#define SETLEN(A,L)  setint (ORIGIN(A),(L))
>>>>#define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
>>>>#define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
>>>
>>>I'd simplify all this with a struct for the header.
>>
>>I am sure the rules of aliasing allow it.
>
> I meant I am *not* sure.

I am sure it is allowed.  How could it not be?  It's what one does all
the time.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#138129 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-19 22:24 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181119222453.02f85be1e85a75d64ff16bee@gmail.com>
In reply to#138117
Ben Bacarisse to Anton Sheplev:

> > > > /* ------------ Macros to access the fields of a dynamic array: ------------- */
> > > > #define SHIFT(A,S)   (((char*)A) - (S))
> > > > #define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
> > > > #define ORIGIN(A)    SHIFT(A, OFFSET)
> > > > #define GETLEN(A)    getint (ORIGIN(A))
> > > > #define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
> > > > #define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
> > > > #define SETLEN(A,L)  setint (ORIGIN(A),(L))
> > > > #define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
> > > > #define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
> > >
> > > I'd simplify all this with a struct for the header.
> >
> > I am [not] sure the rules of aliasing allow it.
>
> I am sure it is allowed.  How could it not be?  It's what
> one does all the time.

I don't think it can work, but correct it me if I am wrong.
For the array to work, the allocted object must have the
effective type compatible with the element type that the
user wants.  For a dynamic array of int, the allocated
object must have the effective type int.  6.5p6 (in C99),
prevents any write accesses save through a char lvalue if
one wants to keep the effective type of the allocated object
unchanged.  And 6.5p7 forbids any read accesses save those
through a char lvalue because they will not alias (the user-
supplied type of the array element being inacessible to the
library code).  Can you indicate my error or maybe post an
example of accessing an allocated object of unknown type
through a struct for the header?

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138130 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

Fromjameskuyper@alumni.caltech.edu
Date2018-11-19 12:33 -0800
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<f6c78a4e-e93b-4029-8450-1edb22d2f2c7@googlegroups.com>
In reply to#138129
On Monday, November 19, 2018 at 2:25:05 PM UTC-5, Anton Shepelev wrote:
> Ben Bacarisse to Anton Sheplev:
> 
> > > > > /* ------------ Macros to access the fields of a dynamic array: ------------- */
> > > > > #define SHIFT(A,S)   (((char*)A) - (S))
> > > > > #define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
> > > > > #define ORIGIN(A)    SHIFT(A, OFFSET)
> > > > > #define GETLEN(A)    getint (ORIGIN(A))
> > > > > #define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
> > > > > #define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
> > > > > #define SETLEN(A,L)  setint (ORIGIN(A),(L))
> > > > > #define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
> > > > > #define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
> > > >
> > > > I'd simplify all this with a struct for the header.
> > >
> > > I am [not] sure the rules of aliasing allow it.
> >
> > I am sure it is allowed.  How could it not be?  It's what
> > one does all the time.
> 
> I don't think it can work, but correct it me if I am wrong.
> For the array to work, the allocted object must have the
> effective type compatible with the element type that the
> user wants.  For a dynamic array of int, the allocated
> object must have the effective type int.  6.5p6 (in C99),
> prevents any write accesses save through a char lvalue if
> one wants to keep the effective type of the allocated object
> unchanged.  And 6.5p7 forbids any read accesses save those
> through a char lvalue because they will not alias (the user-
> supplied type of the array element being inacessible to the
> library code).  Can you indicate my error or maybe post an
> example of accessing an allocated object of unknown type
> through a struct for the header?

Let's look, for example at your

static int getint(void* source)
{  union intalias ia;
   memcpy(&ia, source, sizeof(int));
   return ia.idata;
} 

memcpy() copies from the array one character at a time, which is
allowed. ia.idata has a declared type of int, and therefore has an
effective type of int, and is guaranteed to be correctly aligned to
store an int, so reading it is allowed, so long as it contains a valid
representation of an int. Assuming a valid representation of an int
object was copied into the array (even if the place it copied to was
incorrectly aligned to store an int), then the memcpy() copied that
valid representation into ia.idata, so it should be fine.
Note: the union is unnecessary - the following is equivalent and
simpler:

static int getint(void* source)
{  int idata;
   memcpy(&idata, source, sizeof(int));
   return idata;
}

If you still think there's a portability problem, could you be more
specific about which lvalue you're referring to that has a mis-match to
the corresponding effective type?

[toc] | [prev] | [next] | [standalone]


#138132 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-20 00:34 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181120003418.b4efa6451ba84ead499f42a2@gmail.com>
In reply to#138130
James Kuyper to Anton Shepelev:

> > Ben Bacarisse to Anton Sheplev:
> >
> > > > /* ------------ Macros to access the fields of a dynamic array: ------------- */
> > > > #define SHIFT(A,S)   (((char*)A) - (S))
> > > > #define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
> > > > #define ORIGIN(A)    SHIFT(A, OFFSET)
> > > > #define GETLEN(A)    getint (ORIGIN(A))
> > > > #define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
> > > > #define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
> > > > #define SETLEN(A,L)  setint (ORIGIN(A),(L))
> > > > #define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
> > > > #define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
> > >
> > > I'd simplify all this with a struct for the header.
> >
> > I don't think it can work, but correct it me if I am
> > wrong.  For the array to work, the allocted object must
> > have the effective type compatible with the element type
> > that the user wants.  For a dynamic array of int, the
> > allocated object must have the effective type int.
> > 6.5p6 (in C99), prevents any write accesses save through
> > a char lvalue if one wants to keep the effective type of
> > the allocated object unchanged.  And 6.5p7 forbids any
> > read accesses save those through a char lvalue because
> > they will not alias (the user-supplied type of the array
> > element being inacessible to the library code).  Can you
> > indicate my error or maybe post an example of accessing
> > an allocated object of unknown type through a struct for
> > the header?
>
> Let's look, for example at your
> static int getint(void* source)
> {  union intalias ia;
>    memcpy(&ia, source, sizeof(int));
>    return ia.idata;
> }
> memcpy() copies from the array one character at a time,
> which is allowed. ia.idata has a declared type of int, and
> therefore has an effective type of int, and is guaranteed
> to be correctly aligned to store an int, so reading it is
> allowed, so long as it contains a valid representation of
> an int. Assuming a valid representation of an int object
> was copied into the array (even if the place it copied to
> was incorrectly aligned to store an int), then the
> memcpy() copied that valid representation into ia.idata,
> so it should be fine.

Of course, I wrote it specifically to comply with the
aliasing rules.

> Note: the union is unnecessary - the following is
> equivalent and simpler:
> static int getint(void* source)
> {  int idata;
>    memcpy(&idata, source, sizeof(int));
>    return idata;
> }

Indeed.  Thanks.

> If you still think there's a portability problem, could
> you be more specific about which lvalue you're referring
> to that has a mis-match to the corresponding effective
> type?

I think that Ben's proposal to access the metadata at the
header of the allocated object direcly via this struct:

  struct data {
      int cap, len, size;
      union {
          long double dummy_align[1];
          char bytes[sizeof (long double)];
      } data;
  };

is dangerous because it violates aliasing.  If I have
understood him, he means to access the metadata by
converting the pointer to the allocated object into a
pointer to this struct.  According to 6.3.2.3p7, the only
guarrantee of such a conversion is that of the round trip.
Futhermore, read access through this struct to cap, len, and
size is impossible because the effective type of the
allocated object is, generally, not int, whereas write
access to those fields will change the effective type and
break the array for user.  May be I understood Ben wrong,
whence my request of an example of his proposal.  May be I
misunderstand the concepts of effective type and aliasing.

Looks like a generic dynamic array in standard C is not as
easy as I thought.

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138142 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

Fromjameskuyper@alumni.caltech.edu
Date2018-11-19 14:38 -0800
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<a39bd056-6a42-4d36-a66d-9cb72920aab0@googlegroups.com>
In reply to#138132
On Monday, November 19, 2018 at 4:34:25 PM UTC-5, Anton Shepelev wrote:
> James Kuyper to Anton Shepelev:
...
> > If you still think there's a portability problem, could
> > you be more specific about which lvalue you're referring
> > to that has a mis-match to the corresponding effective
> > type?
> 
> I think that Ben's proposal to access the metadata at the
> header of the allocated object direcly via this struct:
> 
>   struct data {
>       int cap, len, size;
>       union {
>           long double dummy_align[1];
>           char bytes[sizeof (long double)];
>       } data;
>   };
> 
> is dangerous because it violates aliasing.  If I have
> understood him, he means to access the metadata by
> converting the pointer to the allocated object into a
> pointer to this struct.

I was assuming that he meant copying the array into an object of the
struct type, which has no such problems. It appears I was mistaken.

[toc] | [prev] | [next] | [standalone]


#138144 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-20 00:43 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<87wop8fuja.fsf@bsb.me.uk>
In reply to#138142
jameskuyper@alumni.caltech.edu writes:

> On Monday, November 19, 2018 at 4:34:25 PM UTC-5, Anton Shepelev wrote:
>> James Kuyper to Anton Shepelev:
> ...
>> > If you still think there's a portability problem, could
>> > you be more specific about which lvalue you're referring
>> > to that has a mis-match to the corresponding effective
>> > type?
>> 
>> I think that Ben's proposal to access the metadata at the
>> header of the allocated object direcly via this struct:
>> 
>>   struct data {
>>       int cap, len, size;
>>       union {
>>           long double dummy_align[1];
>>           char bytes[sizeof (long double)];
>>       } data;
>>   };
>> 
>> is dangerous because it violates aliasing.  If I have
>> understood him, he means to access the metadata by
>> converting the pointer to the allocated object into a
>> pointer to this struct.
>
> I was assuming that he meant copying the array into an object of the
> struct type, which has no such problems. It appears I was mistaken.

I have posted code.  If it's wrong, please tell me why.  It does fairly
standard things.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#138145 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2018-11-19 21:44 -0500
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<psvsek$943$1@dont-email.me>
In reply to#138144
On 11/19/18 19:43, Ben Bacarisse wrote:
> jameskuyper@alumni.caltech.edu writes:
> 
>> On Monday, November 19, 2018 at 4:34:25 PM UTC-5, Anton Shepelev wrote:
>>> James Kuyper to Anton Shepelev:
>> ...
>>>> If you still think there's a portability problem, could
>>>> you be more specific about which lvalue you're referring
>>>> to that has a mis-match to the corresponding effective
>>>> type?
>>>
>>> I think that Ben's proposal to access the metadata at the
>>> header of the allocated object direcly via this struct:
>>>
>>>   struct data {
>>>       int cap, len, size;
>>>       union {
>>>           long double dummy_align[1];
>>>           char bytes[sizeof (long double)];
>>>       } data;>>>   };
>>>
>>> is dangerous because it violates aliasing.  If I have
>>> understood him, he means to access the metadata by
>>> converting the pointer to the allocated object into a
>>> pointer to this struct.
>>
>> I was assuming that he meant copying the array into an object of the
>> struct type, which has no such problems. It appears I was mistaken.
> 
> I have posted code.  If it's wrong, please tell me why.  It does fairly
> standard things.

I'm just stating what I assumed - I didn't actually put much thought
into that assumption at the time I made it. I was paying more attention
to what Anton was saying than to what you were saying. I had assumed
from his comment that you were taking dynamically allocate memory that
had been filled in from an external by means that did not give any of
that memory an effective type (such as a call to fread()), in which case
there would be aliasing prolems. However, if, for instance, all calls to
da_len() are always preceded by calls to da_setlen() using the same
memory, then there shouldn't be any aliasing problems.

[toc] | [prev] | [next] | [standalone]


#138157 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

Fromjadill33@gmail.com
Date2018-11-20 07:11 -0800
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<4f3a93f3-1abc-4292-b171-903582437899@googlegroups.com>
In reply to#138144
On Monday, November 19, 2018 at 7:43:28 PM UTC-5, Ben Bacarisse wrote:
> j...@alumni.caltech.edu writes:
> 
> > On Monday, November 19, 2018 at 4:34:25 PM UTC-5, Anton Shepelev wrote:
> >> James Kuyper to Anton Shepelev:
> > ...
> >> > If you still think there's a portability problem, could
> >> > you be more specific about which lvalue you're referring
> >> > to that has a mis-match to the corresponding effective
> >> > type?
> >> 
> >> I think that Ben's proposal to access the metadata at the
> >> header of the allocated object direcly via this struct:
> >> 
> >>   struct data {
> >>       int cap, len, size;
> >>       union {
> >>           long double dummy_align[1];
> >>           char bytes[sizeof (long double)];
> >>       } data;
> >>   };
> >> 
> >> is dangerous because it violates aliasing.  If I have
> >> understood him, he means to access the metadata by
> >> converting the pointer to the allocated object into a
> >> pointer to this struct.
> >
> > I was assuming that he meant copying the array into an object of the
> > struct type, which has no such problems. It appears I was mistaken.
> 
> I have posted code.  If it's wrong, please tell me why.  It does fairly
> standard things.

On Windows, long double does not necessarily share the maximum alignment
of any type.  In fact, when I run my alignof code, it shows long double
has a size of 12, and an alignment of '4', not '8' like type double!

Implementations do weird things.

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#138158 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

Frombart4858@gmail.com
Date2018-11-20 10:02 -0800
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<38c79860-8042-4b08-9a6c-99fd88fde2ae@googlegroups.com>
In reply to#138157
On Tuesday, 20 November 2018 15:12:01 UTC, jadi...@gmail.com  wrote:
> On Monday, November 19, 2018 at 7:43:28 PM UTC-5, Ben Bacarisse wrote:
> > j...@alumni.caltech.edu writes:
> > 
> > > On Monday, November 19, 2018 at 4:34:25 PM UTC-5, Anton Shepelev wrote:
> > >> James Kuyper to Anton Shepelev:
> > > ...
> > >> > If you still think there's a portability problem, could
> > >> > you be more specific about which lvalue you're referring
> > >> > to that has a mis-match to the corresponding effective
> > >> > type?
> > >> 
> > >> I think that Ben's proposal to access the metadata at the
> > >> header of the allocated object direcly via this struct:
> > >> 
> > >>   struct data {
> > >>       int cap, len, size;
> > >>       union {
> > >>           long double dummy_align[1];
> > >>           char bytes[sizeof (long double)];
> > >>       } data;
> > >>   };
> > >> 
> > >> is dangerous because it violates aliasing.  If I have
> > >> understood him, he means to access the metadata by
> > >> converting the pointer to the allocated object into a
> > >> pointer to this struct.
> > >
> > > I was assuming that he meant copying the array into an object of the
> > > struct type, which has no such problems. It appears I was mistaken.
> > 
> > I have posted code.  If it's wrong, please tell me why.  It does fairly
> > standard things.
> 
> On Windows, long double does not necessarily share the maximum alignment
> of any type.  In fact, when I run my alignof code, it shows long double
> has a size of 12, and an alignment of '4', not '8' like type double!
> 
> Implementations do weird things.

On Windows, I've seen these various sizes and alignments (in bytes) for long double:

      Size   Align    Target size (all x86 or x64)
       8       8       64 bits
      16       8       64
      12       8       32
      10       2       32
      16      16       64
      12       4       32

On Linux:
      16      16       64
      12       4       32

So it's not just Windows. The list is short for Linux because I don't have many compilers for it.

-- 
bart

[toc] | [prev] | [next] | [standalone]


#138138 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-19 22:20 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<878t1ohfp2.fsf@bsb.me.uk>
In reply to#138129
Anton Shepelev <anton.txt@gmail.com> writes:

> Ben Bacarisse to Anton Sheplev:
>
>> > > > /* ------------ Macros to access the fields of a dynamic array: ------------- */
>> > > > #define SHIFT(A,S)   (((char*)A) - (S))
>> > > > #define OFFSET       ( sizeof(size_t) + 2*sizeof(int))
>> > > > #define ORIGIN(A)    SHIFT(A, OFFSET)
>> > > > #define GETLEN(A)    getint (ORIGIN(A))
>> > > > #define GETSIZE(A)   getsize(SHIFT((A),sizeof(size_t)))
>> > > > #define GETCAP(A)    getint (SHIFT((A),sizeof(size_t)+sizeof(int)))
>> > > > #define SETLEN(A,L)  setint (ORIGIN(A),(L))
>> > > > #define SETSIZE(A,S) setsize(SHIFT((A),sizeof(size_t)),S)
>> > > > #define SETCAP(A,C)  setint (SHIFT((A),sizeof(size_t)+sizeof(int)),(C))
>> > >
>> > > I'd simplify all this with a struct for the header.
>> >
>> > I am [not] sure the rules of aliasing allow it.
>>
>> I am sure it is allowed.  How could it not be?  It's what
>> one does all the time.
>
> I don't think it can work, but correct it me if I am wrong.
> For the array to work, the allocted object must have the
> effective type compatible with the element type that the
> user wants.

Ah, cross purposes.  I was talking about your meta-data.  I'd simplify
all those macros by using a struct for the meta-data.

> For a dynamic array of int, the allocated
> object must have the effective type int.  6.5p6 (in C99),
> prevents any write accesses save through a char lvalue if
> one wants to keep the effective type of the allocated object
> unchanged.

No.  I envisage two kinds of access.  In one, the user gets a void *
(forgive me, I don't want to stick with exactly your API) and will do
something like

  int *elemptr = da_addemp(&a);
  if (elemptr) *elemptr = 42;

In the other, the element is set inside your da_add function using
memcpy.  Your function would have to use memcpy because they have only a
void * and a size to go on.  Both of these make the effective type an
int.

For read accesses, if the user has a void *, converting to int * and
dereferencing it is allowed (the lavlue used has the same type as the
effective type of the object neing accessed), and there would be no
problem if your function were it to use memcpy to extract the value
because memcpy copies characters.

> And 6.5p7 forbids any read accesses save those
> through a char lvalue because they will not alias (the user-
> supplied type of the array element being inacessible to the
> library code).

I can't parse this.  I don't know what "they" refers to.

> Can you indicate my error or maybe post an
> example of accessing an allocated object of unknown type
> through a struct for the header?

Here's how I would do it (not tested much):

#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "da.h"


struct da_meta_data {
     size_t capacity, length, element_size;
     max_align_t data[];
};


static struct da_meta_data *da_alloc(void *a, size_t cap, size_t size)
{
     if (a) a = (struct da_meta_data *)a - 1;
     struct da_meta_data *new = realloc(a, sizeof *new + cap * size);
     if (new)
          new->capacity = cap;
     else free(a);
     return new;
}

static size_t da_element_size(void *a)
{
     return ((struct da_meta_data *)a - 1)->element_size;
}


void *da_new(size_t size)
{
     struct da_meta_data *mdp = da_alloc(0, 1, size);
     if (mdp) {
          mdp->element_size = size;
          mdp->length = 0;
     }
     return mdp->data;
}

void *da_add(void *a, void *data)
{
     void *addr;
     a = da_addemp(a, &addr);
     if (a) memcpy(addr, data, da_element_size(a));
     return a;
}

void *da_setlen(void *a, size_t len)
{
     size_t newcap = 1;
     while (newcap < len)
          newcap <<= 1;
     struct da_meta_data *new = da_alloc(a, newcap, da_element_size(a));
     if (new) new->length = len;
     return new->data;
}

void *da_addemp(void *a, void **data)
{
     struct da_meta_data *mdp = (struct da_meta_data *)a - 1;
     if (mdp->length == mdp->capacity) {
          mdp = da_alloc(a, mdp->capacity * 2, mdp->element_size);
          if (!mdp)
               return 0;
     }
     *data = (char *)mdp->data + mdp->element_size * mdp->length;
     mdp->length += 1;
     return mdp->data;
}

void da_free(void *a)
{
     if (a) free((struct da_meta_data *)a - 1);
}

size_t da_len(void *a)
{
     return ((struct da_meta_data *)a - 1)->length;
}

==========================================================
The .h file is just:
==========================================================
void *da_new(size_t size);
void  da_free(void *a);

size_t da_len(void *a);

void *da_setlen(void *a, size_t len);
void *da_add(void *a, void *data);
void *da_addemp(void *a, void **data);


-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#138147 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-20 14:01 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181120140102.05f98f04f3ea664fa30807e2@g{oogle}mail.com>
In reply to#138138
Ben Bacarisse:

>Anton Shepelev:
>
>>I think that Ben's proposal to access the metadata at the
>>header of the allocated object direcly via this struct:
>>  struct data {
>>      int cap, len, size;
>>      union {
>>          long double dummy_align[1];
>>          char bytes[sizeof (long double)];
>>      } data;
>>  };
>>
>>is dangerous because it violates aliasing.  If I have
>>understood him, he means to access the metadata by
>>converting the pointer to the allocated object into a
>>pointer to this struct.  According to 6.3.2.3p7, the only
>>guarrantee of such a conversion is that of the round trip.
>>Futhermore, read access through this struct to cap, len,
>>and size is impossible because the effective type of the
>>allocated object is, generally, not int, whereas write
>>access to those fields will change the effective type and
>>break the array for user.  May be I understood Ben wrong,
>>whence my request of an example of his proposal.  May be I
>>misunderstand the concepts of effective type and aliasing.
>
>I have posted code.  If it's wrong, please tell me why.  It
>does fairly standard things.

Thanks for the code, Ben.  Below is my understanding why it
is wrong:

>struct da_meta_data {
>     size_t capacity, length, element_size;
>     max_align_t data[];
>};
>
>
>static struct da_meta_data *da_alloc(void *a, size_t cap, size_t size)
>{
>     if (a) a = (struct da_meta_data *)a - 1;
>     struct da_meta_data *new = realloc(a, sizeof *new + cap * size);
>     if (new)
>          new->capacity = cap;
>     else free(a);
>     return new;
>}

So, da_alloc will set the effective type to
struct da_meta_data.

>static size_t da_element_size(void *a)
>{
>     return ((struct da_meta_data *)a - 1)->element_size;
>}

This can work only if the effectitve type is
struct da_meta_data.

>void *da_new(size_t size)
>{
>     struct da_meta_data *mdp = da_alloc(0, 1, size);
>     if (mdp) {
>          mdp->element_size = size;
>          mdp->length = 0;
>     }
>     return mdp->data;
>}

After da_new(), the effective type will be
struct da_meta_data.

>void *da_setlen(void *a, size_t len)
>{
>     size_t newcap = 1;
>     while (newcap < len)
>          newcap <<= 1;
>     struct da_meta_data *new = da_alloc(a, newcap, da_element_size(a));
>     if (new) new->length = len;
>     return new->data;
>}

I think it may break because the effective type of the
object that `a' points to will likely have the user-supplied
element type as its effective type (e.g., `double' for a
dynamic array of `double').  Therefore:

  1.  da_element_size() can fail because it expects an
      effective type of struct da_meta_data.

  2.  da_setlen() sets the effective type to
      struct da_meta_data, making it inaccessible for
      reading by the user as an array of his desired type.

The same applies to the other functions, e.g.:

>void da_free(void *a)
>{
>     if (a) free((struct da_meta_data *)a - 1);
>}

Cannot read from `a' wtih struct da_meta_data because its is
likely to have an incompatible effective type (the type of
the array element).

>size_t da_len(void *a)
>{
>     return ((struct da_meta_data *)a - 1)->length;
>}

The same.  Although your code may work, and it is easonable
and logical to expect it to work, the authors of C compilers
that take the Standard to the letter think otherwise,
renouncing any responsibility for the ensurance of non-
standard aliasing even when it is evident from staic
analysis.  supercat calls such compilers "obtuse":

   https://stackoverflow.com/a/38162236/2862241

and Linus Torvalds used some harsher epithet and, IIRC, has
fno-strict-aliasing on.

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138148 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromMelzzzzz <Melzzzzz@zzzzz.com>
Date2018-11-20 11:07 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<RVRID.163845$RM7.37232@fx24.am4>
In reply to#138147
On 2018-11-20, Anton Shepelev <anton.txt@g{oogle}mail.com> wrote:
>
> and Linus Torvalds used some harsher epithet and, IIRC, has
> fno-strict-aliasing on.

Strict aliasing does not have to do anything in language that
allocates raw memory. In C++ there si new that returns exact type but
malloc? 
>


-- 
press any key to continue or any other to quit...

[toc] | [prev] | [next] | [standalone]


#138150 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-20 15:12 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181120151204.5fbe10f69868378134d68159@g{oogle}mail.com>
In reply to#138148
Melzzzzz to Anton Shepelev:

>>and Linus Torvalds used some harsher epithet and, IIRC,
>>has fno-strict-aliasing on.
>
>Strict aliasing does not have to do anything in language
>that allocates raw memory. In C++ there si new that returns
>exact type but malloc?

I do not understand you.  Some references:

   Linus on aliasing:
   http://www.yodaiken.com/2018/06/07/torvalds-on-aliasing/

   The Strict Aliasing Situation is Pretty Bad:
   https://blog.regehr.org/archives/1307

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138152 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2018-11-20 08:15 -0500
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<pt11ds$sa9$1@dont-email.me>
In reply to#138147
On 11/20/18 06:01, Anton Shepelev wrote:
> Ben Bacarisse:
...
> Thanks for the code, Ben.  Below is my understanding why it
> is wrong:
> 
>> struct da_meta_data {
>>     size_t capacity, length, element_size;
>>     max_align_t data[];
>> };
>>
>>
>> static struct da_meta_data *da_alloc(void *a, size_t cap, size_t size)
>> {
>>     if (a) a = (struct da_meta_data *)a - 1;
>>     struct da_meta_data *new = realloc(a, sizeof *new + cap * size);
>>     if (new)
>>          new->capacity = cap;
>>     else free(a);
>>     return new;
>> }
> 
> So, da_alloc will set the effective type to
> struct da_meta_data.
> 
>> static size_t da_element_size(void *a)
>> {
>>     return ((struct da_meta_data *)a - 1)->element_size;
>> }
> 
> This can work only if the effectitve type is
> struct da_meta_data.
> 
>> void *da_new(size_t size)
>> {
>>     struct da_meta_data *mdp = da_alloc(0, 1, size);
>>     if (mdp) {
>>          mdp->element_size = size;
>>          mdp->length = 0;
>>     }
>>     return mdp->data;
>> }
> 
> After da_new(), the effective type will be
> struct da_meta_data.
> 
>> void *da_setlen(void *a, size_t len)
>> {
>>     size_t newcap = 1;
>>     while (newcap < len)
>>          newcap <<= 1;
>>     struct da_meta_data *new = da_alloc(a, newcap, da_element_size(a));
>>     if (new) new->length = len;
>>     return new->data;
>> }
> 
> I think it may break because the effective type of the
> object that `a' points to will likely have the user-supplied
> element type as its effective type (e.g., `double' for a
> dynamic array of `double').  Therefore:

I was assuming that the user-supplied data would have essentially the
structure:

{
     size_t capacity, length, element_size;
     my_type data[];
};

So there shouldn't be any aliasing issues with the first three members
of the struct. Extracting the elements of the data array would require
conversion of a pointer back to the user's type before dereferencing it,
which would result in an lvalue matching the effective type of the data.

> 
>   1.  da_element_size() can fail because it expects an
>       effective type of struct da_meta_data.

It refers to struct da_meta_data, but the only lvalue it actually
deferences is the element_size member of that struct, which should have
the same type (int) as the effective type of the memory that it refers
to. Similarly for the other functions you mention.

> 
>   2.  da_setlen() sets the effective type to
>       struct da_meta_data, making it inaccessible for
>       reading by the user as an array of his desired type.

It doesn't write the entire struct object, so it doesn't set the
effective type of the entire struct object. It sets the effective type
only for the the memory it actually writes, which is "int".

[toc] | [prev] | [next] | [standalone]


#138160 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-20 23:08 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181120230835.f7b3a89f2ed4aa738fa0fa3b@gmail.com>
In reply to#138152
James Kuyper:

> I was assuming that the user-supplied data would have essentially the
> structure:
>
> {
>      size_t capacity, length, element_size;
>      my_type data[];
> };

No, Ben proposes (let him correct me if I misunderstand)
that it be the internal structure used exclusively inside
the dynamic array library, to which the user of the library
has no access.  From the user's point of view, a dynamic
array is a pointer to an object of the type of the array
element.  This type, in turn, is unknown and inaccessible to
the dynamic array library, which knows only its size.  See
the header file of the library:

/* `a' is the array, declared as a pointer of the desired type and  `data' is
   the contents of an array element. The functions returning `void*' return the
   new array variable, potentially modified due to reallocation. It is NULL in
   case of an error. */
void* da_new   ( size_t size );            /* create an empty array */
void  da_free  ( void * a );               /* free an array         */

void* da_setlen( void * a, int len );      /* set the length        */
int   da_len   ( void * a );               /* get the length        */
void* da_add   ( void * a, void * data );  /* add a new element     */
void* da_addemp( void * a, void ** data ); /* add an empty element  */

and the usage sample:

#include <stdio.h>
#include <string.h>
#include "dynarray.h"

int main( int argc, char** argv )
{  int *a, v, i, l, excode;
   void* vP;

   excode = 1;
   a = da_new( sizeof( int ) );
   if( a == NULL ) goto ERROR;
   a = da_setlen( a, 2 );
   if( a == NULL ) goto ERROR;

   a[0] = 0;
   a[1] = 1;
   a = da_setlen( a, 4 );
   if( a == NULL ) goto ERROR;
   a[2] = 2;
   a[3] = 3;

   v = 4;
   a = da_add( a, &v );
   if( a == NULL ) goto ERROR;

   v = 5;
   a = da_addemp( a, &vP );
   if( a == NULL ) goto ERROR;
   memcpy( vP, &v, sizeof( int ) );

   l = da_len( a );
   for( i = 0; i < l; i++ )
   {  printf("%i ", a[i]);  }

   excode = 0;
   da_free( a );
ERROR: return excode;
}

> So there shouldn't be any aliasing issues with the first
> three members of the struct.  Extracting the elements of
> the data array would require conversion of a pointer back
> to the user's type before dereferencing it, which would
> result in an lvalue matching the effective type of the
> data.

I think that after my clarification above it is irrelevant:
the type of the array element and the type/sturcture of its
internal metadata are completely decoupled and isolated from
each other, which I think requires that the library access
it via char* in order a) not to break aliasing during read
accesses and b) not to change the effective type during
write accesses.

> > da_element_size() can fail because it expects an
> > effective type of struct da_meta_data.
>
> It refers to struct da_meta_data, but the only lvalue it
> actually deferences is the element_size member of that
> struct, which should have the same type (int) as the
> effective type of the memory that it refers to. Similarly
> for the other functions you mention.

> > > static size_t da_element_size(void *a)
> > > {
> > >      return ((struct da_meta_data *)a - 1)->element_size;
> > > }
> >
> > da_element_size() can fail because it expects an
> > effective type of struct da_meta_data.
>
> It refers to struct da_meta_data, but the only lvalue it
> actually deferences is the element_size member of that
> struct ->

Please, explain.  As I understand, the -> operator is
entirely equivalent to a combination of * and . operators.
If we have `struct mystruc *sP', then `(*sP).field' is
interchangeable with `sP->field'.  Is it not so?  If I am
right then the type for the access is that of the whole
structure.

> -> which should have the same type (int) as the effective
> type of the memory that it refers to.

In order for the array to be functional for the user, it
must have the effective type of the array element, e.g.
double for an array of double.  Therefore, an unmodifying
access to the allocated object through an int pointer is a
violation of aliasing unless, serendipitously, the array
element is also of type `int'.  What am I missing (but see
below:)?

> da_setlen() sets the effective type to struct
> da_meta_data, making it inaccessible for reading by the
> user as an array of his desired type.

The standard states clealy that each invocation of malloc()
creates a *single* allocated object of specified size.
Nowhere does it allow for such an object to be divided into
sub-objects (shall we say?) with different effective types.
I have concluded that at most one effective type may be
associated with each allocated object, and therefore all
data allocated for the array has the same effective type.
Am I wrong?

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138163 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

Fromjameskuyper@alumni.caltech.edu
Date2018-11-20 14:13 -0800
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<db144560-9b27-4b9f-9b65-21a0004adbcc@googlegroups.com>
In reply to#138160
On Tuesday, November 20, 2018 at 3:08:44 PM UTC-5, Anton Shepelev wrote:
> James Kuyper:
> 
> > I was assuming that the user-supplied data would have essentially the
> > structure:
> >
> > {
> >      size_t capacity, length, element_size;
> >      my_type data[];
> > };
> 
> No, Ben proposes (let him correct me if I misunderstand)
> that it be the internal structure used exclusively inside
> the dynamic array library, to which the user of the library
> has no access.  From the user's point of view, a dynamic
> array is a pointer to an object of the type of the array
> element.  This type, in turn, is unknown and inaccessible to
> the dynamic array library, which knows only its size.  See
> the header file of the library:
> 
> /* `a' is the array, declared as a pointer of the desired type and  `data' is
>    the contents of an array element. The functions returning `void*' return the
>    new array variable, potentially modified due to reallocation. It is NULL in
>    case of an error. */
> void* da_new   ( size_t size );            /* create an empty array */
> void  da_free  ( void * a );               /* free an array         */
> 
> void* da_setlen( void * a, int len );      /* set the length        */
> int   da_len   ( void * a );               /* get the length        */
> void* da_add   ( void * a, void * data );  /* add a new element     */
> void* da_addemp( void * a, void ** data ); /* add an empty element  */
> 
> and the usage sample:

I'll insert comments about this usage sample explaining how I currently
understand the issue relevant the to anti-aliasing rule.

> #include <stdio.h>
> #include <string.h>
> #include "dynarray.h"
> 
> int main( int argc, char** argv )
> {  int *a, v, i, l, excode;
>    void* vP;
> 
>    excode = 1;
>    a = da_new( sizeof( int ) );
>    if( a == NULL ) goto ERROR;

At this point, ((struct da_meta_data*)a-1)->capacity, ->element_size and
->length have been written to, and since those lvalues have the type
"int", the corresponding pieces of memory have the effective type of
"int".

>    a = da_setlen( a, 2 );
>    if( a == NULL ) goto ERROR;

The call to realloc() might have resulted in the object being moved, but
those fields retain their effective types even if they're in a new
location.

>    a[0] = 0;
>    a[1] = 1;

These two statements give the corresponding pieces of memory the
effective type of "int".

>    a = da_setlen( a, 4 );
>    if( a == NULL ) goto ERROR;

Again, the realloc() call may have moved the objects, but all of the
parts with effective types retain those effective types.

>    a[2] = 2;
>    a[3] = 3;

And those statements give the corresponding pieces of memory the
effective type of "int".

>    v = 4;
>    a = da_add( a, &v );
>    if( a == NULL ) goto ERROR;

This results in the values of ((struct da_meta_data*)a-1)->length and
->capacity being read, which is not an aliasing problem because those
pieces of memory have already been given an effective type of "int". As
before, if realloc() moves the object, the effective types are carried
over with it. The memcpy() call gives the target piece of memory the
effective type of "int".

>    v = 5;
>    a = da_addemp( a, &vP );
>    if( a == NULL ) goto ERROR;
>    memcpy( vP, &v, sizeof( int ) );

Together those statements have the same effect as a call to da_add() -
so the same comments apply.

>    l = da_len( a );

This reads the value stored in ((struct da_meta_data*)a-1)->length,
which has been given an effective type of "int" by the previous write to
that memory, and there is therefore a match between the lvalue type and
the effective type - there is no aliasing problem.

>    for( i = 0; i < l; i++ )
>    {  printf("%i ", a[i]);  }

For each value of i, a[i] refers to a block of memory that has already
been written to with an lvalue of type "int", making that the effective
type of that piece of memory, so there's no aliasing problem with using
an lvalue of that same type to retrieve that value.

> > So there shouldn't be any aliasing issues with the first
> > three members of the struct.  Extracting the elements of
> > the data array would require conversion of a pointer back
> > to the user's type before dereferencing it, which would
> > result in an lvalue matching the effective type of the
> > data.
> 
> I think that after my clarification above it is irrelevant:
> the type of the array element and the type/sturcture of its
> internal metadata are completely decoupled and isolated from
> each other, which I think requires that the library access
> it via char* in order a) not to break aliasing during read
> accesses and b) not to change the effective type during
> write accesses.

It looks fine to me: every block of memory written to acquires an
effective type matching the type of the lvalue used to write it (always
an int, in the above example), and an lvalue of the same type is used to retrieve that value, so there's no aliasing problem that I can see. 

> > > > static size_t da_element_size(void *a)
> > > > {
> > > >      return ((struct da_meta_data *)a - 1)->element_size;
> > > > }
> > >
> > > da_element_size() can fail because it expects an
> > > effective type of struct da_meta_data.
> >
> > It refers to struct da_meta_data, but the only lvalue it
> > actually deferences is the element_size member of that
> > struct ->
> 
> Please, explain.  As I understand, the -> operator is
> entirely equivalent to a combination of * and . operators.
> If we have `struct mystruc *sP', then `(*sP).field' is
> interchangeable with `sP->field'.  Is it not so?  If I am
> right then the type for the access is that of the whole
> structure.

You're right about those two expressions being equivalent, but wrong
about both expressions accessing the whole structure. Both expressions
only access a single object of the field's type (and possibly any
padding bytes of the structure (6.2.6.1p6), but do not access any other
part of that structure.

> > -> which should have the same type (int) as the effective
> > type of the memory that it refers to.
> 
> In order for the array to be functional for the user, it
> must have the effective type of the array element, e.g.
> double for an array of double.  Therefore, an unmodifying
> access to the allocated object through an int pointer is a
> violation of aliasing unless, serendipitously, the array
> element is also of type `int'.  What am I missing (but see
> below:)?

The array elements do in fact have the effective type of "int". They are
never accessed, neither for reading or writing, directly through the
data member of struct da_meta_data member named "data". They are written
to and read from using a[i] for various values of 'i', which is an
lvalue of type "int", which is what sets the effective type of the
corresponding memory.

> > da_setlen() sets the effective type to struct
> > da_meta_data, making it inaccessible for reading by the
> > user as an array of his desired type.
> 
> The standard states clealy that each invocation of malloc()
> creates a *single* allocated object of specified size.
> Nowhere does it allow for such an object to be divided into
> sub-objects (shall we say?) with different effective types.

Nowhere does it prohibit it, either. An object is defined simply as a
"region of data storage in the execution environment, the contents of
which can represent values". Objects containing sub-objects are the norm
in C, not the exception. The elements of an array and the members of a
struct are sub-objects, and any object can be accessed as an array of
character type, with each element of that array being a separate
sub-object of the entire object. If an object has a struct type, nothing
is more ordinary than that different sub-objects of that object have
different types.

> I have concluded that at most one effective type may be
> associated with each allocated object, and therefore all
> data allocated for the array has the same effective type.
> Am I wrong?

I believe you are.
If you're right, very large quantitities of real world code (including
all uses of flexible array members such as the one Ben was using) have
undefined behavior due to aliasing violations. It's a pretty common
idiom to allocate a large block of memory, and then use different parts
of that block to store related objects of different types. If those
objects have a fixed size, then you could re-write such code to use a
struct type, but I've seen this approach used, for instance, to store a
struct header and three different arrays of different element types with
lengths determined at run-time, in different parts of a single block of
allocated memory.

[toc] | [prev] | [next] | [standalone]


#138174 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-21 16:38 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181121163818.78148f14a49382c034c16826@g{oogle}mail.com>
In reply to#138163
James Kuyper:

>I'll insert comments about this usage sample explaining how
>I currently understand the issue relevant the to anti-
>aliasing rule.

I fear that I misunderstand the very fundamental concepts of
object, allcoated object, and effective type.  May I please
stop here and ask questions about them before proceeding to
Ben's code?

  1.  Is it correct that malloc creates a single allocated
      object?

  2.  How many effective types can a single allocated object
      have?  I think it is one or zero.

  3.  Can an object be considered as consisting of smaller
      objects, e.g. (assuming a 4-byte int and a 2-byte
      short int) a 4-byte object as two contiguous 2-byte
      objects (when I use it to store two short ints) or
      four contiguous singe-byte objects (when I use it to
      store four characters)?

  4.  Is effective type associated with whatever address
      range is accessed rather than with the whole object
      returned by malloc()?  If so, it must take a lot of
      space for the compiler to track the effective type of
      every single byte of allocated memory.

Consider this example (as simple I as I can make it):

/* assuming sizeof(int) = 4 and sizeof(short)=2 */
void  *vP = malloc( sizeof( int ) );
int   *iP = vP;
short *sP = vP;

*iP  = 5; /* Q1: the effective type of the whole region becomes int? */

sP++;
*sP = 12;
/* Q2: effective type of the latter half of the region in short?   */
/* Q3: what about the effective type of the first half, still int? */

-- 
()  ascii ribbon campaign - against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#138177 — Re: My dynamic arrays module [was:Re: Pointer conversion and alignment]

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2018-11-21 09:05 -0500
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<pt3omq$167$1@dont-email.me>
In reply to#138174
On 11/21/18 08:38, Anton Shepelev wrote:
> James Kuyper:
> 
>> I'll insert comments about this usage sample explaining how
>> I currently understand the issue relevant the to anti-
>> aliasing rule.
> 
> I fear that I misunderstand the very fundamental concepts of
> object, allcoated object, and effective type.  May I please
> stop here and ask questions about them before proceeding to
> Ben's code?
> 
>   1.  Is it correct that malloc creates a single allocated
>       object?

Yes.

>   2.  How many effective types can a single allocated object
>       have?  I think it is one or zero.

Different parts of an allocated object can have different types. This is
particularly obvious if it is used to store a struct containing members
of different types, but you can also write objects of different types to
different parts of allocated memory, giving those parts of the memory
different effective types.

>   3.  Can an object be considered as consisting of smaller
>       objects, e.g. (assuming a 4-byte int and a 2-byte
>       short int) a 4-byte object as two contiguous 2-byte
>       objects (when I use it to store two short ints) or
>       four contiguous singe-byte objects (when I use it to
>       store four characters)?

Yes - there's three different ways in which a C object can contain
smaller sub-objects: Arrays contain smaller objects, which are the
elements of the array. Every object, regardless of type, can be accessed
as an array of character type; the individual characters of that array
are sub-objects of the entire object. Finally, structs may be used to
create heterogeneous collections of sub-objects of different types.


>   4.  Is effective type associated with whatever address
>       range is accessed rather than with the whole object
>       returned by malloc()?  If so, it must take a lot of
>       space for the compiler to track the effective type of
>       every single byte of allocated memory.

I believe it is not necessary for a compiler to store such information.
The distinction is relevant primarily to which optimizations an
implementation is permitted to perform, but what's relevant to those
optimizations is the types of individual expressions in a piece of code.
If pointers to two types that are permitted to alias each other are in
scope in the same block of code, the compiler can always simply not
perform optimizations that would fail if they did alias each other.
Alternatively, it could check the values of those pointers at run-time
to determine whether they alias each other, and executed an optimized
version of the code only if they don't.
They could also, in some cases, perform a compile-time check to confirm
that it's not possible for them to alias each other. To do this in the
general case could be arbitrarily hard. as implied by your question (I'm
sure it can be proven equivalent to the halting problem). However,
compilers are not obligated to perform such analysis, and in real world
compilers they only perform such analysis when it's easy.

> Consider this example (as simple I as I can make it):
> 
> /* assuming sizeof(int) = 4 and sizeof(short)=2 */
> void  *vP = malloc( sizeof( int ) );
> int   *iP = vP;
> short *sP = vP;
> 
> *iP  = 5; /* Q1: the effective type of the whole region becomes int? */

No. Only *iP is written to, so only *iP acquires the effective type of
"int";

> sP++;
> *sP = 12;
> /* Q2: effective type of the latter half of the region in short?   */

Correct. Every write to a piece of dynamically allocated memory can give
it a new, and possibly different, effective type.

> /* Q3: what about the effective type of the first half, still int? */

Assuming that sizeof(short) < sizeof(int) (which need not be true), then
the answer is "No". The effective type applies to the entire "int"
object. Any write that gives any part of that object a new effective
type erases the original effective type.

[toc] | [prev] | [next] | [standalone]


Page 4 of 7 — ← Prev page 1 2 3 [4] 5 6 7  Next page →

Back to top | Article view | comp.lang.c


csiph-web