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 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7  Next page →


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

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

>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.

Is there a reliable way to calculate the padding?  The only
method I see is by assumeing a self-alinged type of data.
What to do in C89 wihtout this assumption?

Chris M. Thomasson calcualtes alignment as the offset of a
field of the required type in a struct after a char field:

#define RALLOC_ALIGN_OF(mp_type) \
   offsetof( \
     struct { \
       char pad_RALLOC_ALIGN_OF; \
       mp_type type_RALLOC_ALIGN_OF; \
     }, \
     type_RALLOC_ALIGN_OF \
   )

How is this offset connected with the alignment requirements
for the type if char is self-aligned and can be located at
any address, including the one immediately before the start
of the type field?

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

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


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

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

> Ben Bacarisse:
>
>>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.
>
> Is there a reliable way to calculate the padding?  The only
> method I see is by assumeing a self-alinged type of data.
> What to do in C89 wihtout this assumption?

I don't think you can do anything that is totally reliable in C89.
Thirty years is a long time ago.  In those days one made loads of
assumptions in C code.

You could put the meta-data at the end of the allocation and get correct
alignment for it by always allocating in multiples of a meta-data
struct.  I.e. you assume that the data is an array of, say,

  struct meta_data { int cap, len, size; }

objects, the last one of which always holds the meta-data.  The start of
the allocated array is guaranteed to be aligned for any type so that
problem vanishes.  I'm sure I don't need point out the down-sides of
this to you!

> Chris M. Thomasson calcualtes alignment as the offset of a
> field of the required type in a struct after a char field:
>
> #define RALLOC_ALIGN_OF(mp_type) \
>    offsetof( \
>      struct { \
>        char pad_RALLOC_ALIGN_OF; \
>        mp_type type_RALLOC_ALIGN_OF; \
>      }, \
>      type_RALLOC_ALIGN_OF \
>    )

The problem with this code is that C89 does not have max_align_t.  For a
generic container, you have to guess what type to use.

> How is this offset connected with the alignment requirements
> for the type if char is self-aligned and can be located at
> any address, including the one immediately before the start
> of the type field?

I don't see what you mean.  There can be no padding at the start of a
struct so if the char immediately precedes the other member, it means
that the compiler is prepared to access such objects without alignment.

But of you are prepared, in C89, to guess the maximally aligned type,
then just use a struct:

  struct data {
      int cap, len, size;
      long double data[1];
  };

In C89 you have to use a 1-element array because C89 does not permit
the [] syntax here.  You allocate data based on the size of this struct
plus however many extra bytes you need for the data.  If you want to be
paranoid about effective types, do this:

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

and always allocate the extra in multiples of the union size.

-- 
Ben.

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


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

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-24 19:24 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181124192405.870012f12c0ac1c1dc8777d8@gmail.com>
In reply to#138110
This is the third edition of my dynamic array
implementation.  I have combined Ben's suggestion to use a
struct for the storage of internal data with jadill33's
suggestion to estimate sufficient alignment by rounding size
to the next power of two.  I have also switched to unsigned
types:

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

/* ----------------------------- Dynamic array ---------------------------------
Memory layout:
  Field: [metadata][padding][offset     ][data...]
  Type:  dynarray_t         unsigned char
*/

struct dynarray_t /* the internal data of the dynamic array */
{  unsigned int   capacity; /* always a power of two            */
   unsigned int   length;   /* number of elements in the array  */
   unsigned short size;     /* size of an array element         */
};

/* Round a number up to the next power of two: */
static unsigned pow2up( unsigned v )
{  unsigned res;
   res = 1;
   while( res < v )
   {  res = res << 1;  }
   return res;
}

/* Get the metatdata of a dynamic array--   */
/* the offset field and internal structure: */
static void getmeta( void *a, struct dynarray_t ** meta, unsigned char * ofs )
{  *ofs = *((char*)a-1);
   *meta = (struct dynarray_t*)((char*)a - *ofs);
}

/* Adjust array to accomodate a new capacity.      */
/* Upon failure, frees the array and returns NULL. */
static struct dynarray_t * adjust
( struct dynarray_t * da, unsigned short size, unsigned cap, unsigned char ofs )
{  struct dynarray_t * da2;
   da2 = realloc( da, size * cap + ofs );
   if( da2 == NULL ) free( da );
   else              da2->capacity = cap;
   return da2;
}

/* ------------ Operations on a dynamic array (public functions) ------------ */
void* da_newl( size_t size, unsigned int len )
{  void              *a;
   unsigned char     ofs;
   struct dynarray_t *da;

   a   = NULL;
   ofs = pow2up( sizeof( struct dynarray_t ) + 1 );
   da  = adjust( NULL, size, pow2up( len ), ofs );
   if( da != NULL )
   {  da->size   = size;
      da->length = len;

      ((char*)da)[ofs-1] = ofs;
      a = (char*)da + ofs;
   }
   return a;
}

void* da_new( size_t size )
{  return da_newl( size, 0 );  }

void* da_setlen( void * a, int len )
{  unsigned int       newcap;
   struct dynarray_t *da;
   unsigned char      ofs;

   getmeta( a, &da, &ofs );
   da->length   = len;
   newcap       = pow2up( len );
   if( da->capacity != newcap )
   {  da->capacity = newcap;
      da = adjust( da, da->size, newcap, ofs );
      if( da != NULL ) a = (char*)da + ofs;
      else             a = NULL;
   }
   return a;
}

void* addemp( struct dynarray_t* da, unsigned char ofs, void ** data )
{  void*    a;
   unsigned dataofs;

   a = NULL;
   dataofs = da->size * da->length;
   da->length++;
   if( da->length == da->capacity )
   {  da->capacity <<= 1;
      da = adjust( da, da->size, da->capacity, ofs );
   }
   if( da != NULL )
   {  a     = (char*)da + ofs;
      *data = (char*)a  + dataofs;
   }
   return a;
}

void* da_addemp( void * a, void ** data )
{  unsigned char      ofs;
   struct dynarray_t* da;

   getmeta( a, &da, &ofs );
   return addemp( da, ofs, data );
}

void* da_add( void * a, void * data )
{  struct dynarray_t * da;
   unsigned char       ofs;
   unsigned int        size;
   void*               addr;

   getmeta( a, &da, &ofs );
   size = da->size;
   a = addemp( da, ofs, &addr );
   if( a != NULL ) memcpy( addr, data, size );
   return a;
}

static struct dynarray_t* getda( void * a )
{  struct dynarray_t * da;
   unsigned char       ofs;
   getmeta( a, &da, &ofs );
   return da;
}

void da_free( void * a )
{  free( getda( a ) );  }

int da_len( void * a )
{  return getda( a )->length;  }

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


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

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-24 21:31 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<87d0qu2mdb.fsf@bsb.me.uk>
In reply to#138221
Anton Shepelev <anton.txt@gmail.com> writes:

> This is the third edition of my dynamic array
> implementation.  I have combined Ben's suggestion to use a
> struct for the storage of internal data with jadill33's
> suggestion to estimate sufficient alignment by rounding size
> to the next power of two.

It looks overly complicated to me.  valgrind reports a bug but I got
lost in a maze of offsets casts.

The biggest complication is managing that offset, but it's a
compile-time value.  For all practical purposes you can calculate it at
compile-time like this:

#define SH_OR(x, n) ((x) | (x) >> (n))

static int offset =
    SH_OR(SH_OR(SH_OR(SH_OR(sizeof(struct dynarray_t)-1, 1), 2), 4), 8) + 1;

<snip>
-- 
Ben.

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


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

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-24 21:46 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<87zhty173m.fsf@bsb.me.uk>
In reply to#138225
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> It looks overly complicated to me.  valgrind reports a bug but I got
> lost in a maze of offsets casts.

"offsets and casts"

-- 
Ben.

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


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

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-25 01:12 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181125011237.7345a0c1c8b26130000e9c2f@gmail.com>
In reply to#138225
Ben Bacarisse to Anton Shepelev:

> > This is the third edition of my dynamic array
> > implementation.  I have combined Ben's suggestion to use
> > a struct for the storage of internal data with
> > jadill33's suggestion to estimate sufficient alignment
> > by rounding size to the next power of two.
>
> It looks overly complicated to me.  valgrind reports a
> bug ->

I failed to interpret its output.  It shows several errors
of the form:

   Invalid write of size 2
   ==20399==    at 0x4C2D98B: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_me
   ==20399==    by 0x400938: da_add (in /home/a/antonius/programs/wcm2/datest)

I am not even sure they indicate bugs.  I have explicitly
tested that in da_add memcpy receives 4 in its third argument.

> -> I got lost in a maze of offsets casts.

And wanted to minimise them, because each cast is potentially
a conversion!

> The biggest complication is managing that offset, but it's
> a compile-time value.

Indeed.  I knew it was compile-time value but didn't know
how to calculate it at compile time, and did not want either
explicit or automatic lazy initialisation of a global
variable.

>For all practical purposes you can calculate it at compile-
>time like this:

>#define SH_OR(x, n) ((x) | (x) >> (n))

>static int offset =
>    SH_OR(SH_OR(SH_OR(SH_OR(sizeof(struct dynarray_t)-1, 1), 2), 4), 8) + 1;

Thanks.  It has simplified my code.

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

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


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

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-11-25 01:39 +0000
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<87va4mylze.fsf@bsb.me.uk>
In reply to#138228
Anton Shepelev <anton.txt@gmail.com> writes:

> Ben Bacarisse to Anton Shepelev:
>
>> > This is the third edition of my dynamic array
>> > implementation.  I have combined Ben's suggestion to use
>> > a struct for the storage of internal data with
>> > jadill33's suggestion to estimate sufficient alignment
>> > by rounding size to the next power of two.
>>
>> It looks overly complicated to me.  valgrind reports a
>> bug ->
>
> I failed to interpret its output.  It shows several errors
> of the form:
>
>    Invalid write of size 2
>    ==20399==    at 0x4C2D98B: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_me
>    ==20399==    by 0x400938: da_add (in /home/a/antonius/programs/wcm2/datest)
>
> I am not even sure they indicate bugs.  I have explicitly
> tested that in da_add memcpy receives 4 in its third argument.

There really is a problem.  If I print the address being written to by
the memcpy in da_add it lies just outside the storage most recently
allocated:

  realloc((nil), 4 * 1 + 16 = 20) = 0x58fdc80 ... 0x58fdc94
  realloc(0x58fdc80, 4 * 2 + 16 = 24) = 0x58fe120 ... 0x58fe138
  realloc(0x58fe120, 4 * 4 + 16 = 32) = 0x58fe180 ... 0x58fe1a0
  memcpy(0x58fe1a0, 0x1fff000208, 4)

(These are from inserted printf statements.)

As you can see, the most recent allocation is for 32 bytes from
0x58fe180 to 0x58fe1a0 and the memcpy starts just outside that block.

I've found valgrind to be highly reliable.  It's report of a write of
size 2 will come from some internal detail about memcpy.

<snip>
-- 
Ben.

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


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

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-25 14:19 +0300
SubjectRe: My dynamic arrays module [was:Re: Pointer conversion and alignment]
Message-ID<20181125141906.7147e2a5008868b3cbec6ca7@gmail.com>
In reply to#138229
Ben Bacarisse to Anton Shepelev:

> > Ben Bacarisse to Anton Shepelev:
> >
> > > > This is the third edition of my dynamic array
> > > > implementation.
> > >
> > > It looks overly complicated to me.  valgrind reports a
> > > bug ->
> >
> > I failed to interpret its output.  It shows several
> > errors of the form:
> >
> >    Invalid write of size 2
> >    ==20399==    at 0x4C2D98B: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_me
> >    ==20399==    by 0x400938: da_add (in /home/a/antonius/programs/wcm2/datest)
> >
> > I am not even sure they indicate bugs.  I have
> > explicitly test that in da_add memcpy receives 4 in its
> > third argument.
>
> There really is a problem.  If I print the address being
> written to by the memcpy in da_add it lies just outside
> the storage most recently allocated:
>
>    realloc((nil), 4 * 1 + 16 = 20) = 0x58fdc80 ... 0x58fdc94
>    realloc(0x58fdc80, 4 * 2 + 16 = 24) = 0x58fe120 ... 0x58fe138
>    realloc(0x58fe120, 4 * 4 + 16 = 32) = 0x58fe180 ... 0x58fe1a0
>    memcpy(0x58fe1a0, 0x1fff000208, 4)
>
> (These are from inserted printf statements.)
>
> As you can see, the most recent allocation is for 32 bytes
> from 0x58fe180 to 0x58fe1a0 and the memcpy starts just
> outside that block.

Thank you!  It was a genuine off-by-one error in the
function for adding an empty element.


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

/* ----------------------------- Dynamic array ---------------------------------
Memory layout:
   |<------ OFS ------>|
   [dynarray_t][padding][data...]
*/

struct dynarray_t /* the internal data of the dynamic array */
{  unsigned int   capacity; /* always a power of two            */
   unsigned int   length;   /* number of elements in the array  */
   unsigned short size;     /* size of an array element         */
};

#define SH_OR(x, n) ((x) | (x) >> (n))
static int OFS =
    SH_OR(SH_OR(SH_OR(SH_OR( sizeof( struct dynarray_t ) -1, 1), 2), 4), 8) + 1;

#define META(a) ((struct dynarray_t*)((char*)(a) - OFS))

/* Round a number up to the next power of two: */
static unsigned pow2up( unsigned v )
{  unsigned res;
   res = 1;
   while( res < v )
   {  res = res << 1;  }
   return res;
}

/* Adjust array to accomodate a new capacity.      */
/* Upon failure, frees the array and returns NULL. */
static struct dynarray_t * adjust
( struct dynarray_t * da, unsigned short size, unsigned cap )
{  struct dynarray_t * da2;
   da2 = realloc( da, size * cap + OFS );
   if( da2 == NULL ) free( da );
   else              da2->capacity = cap;
   return da2;
}

/* ------------ Operations on a dynamic array (public functions) ------------ */
void* da_newl( size_t size, unsigned int len )
{  void              *a;
   struct dynarray_t *da;

   a   = NULL;
   da  = adjust( NULL, size, pow2up( len ) );
   if( da != NULL )
   {  da->size   = size;
      da->length = len;
      a = (char*)da + OFS;
   }
   return a;
}

void* da_new( size_t size )
{  return da_newl( size, 0 );  }

void* da_setlen( void * a, int len )
{  unsigned int       newcap;
   struct dynarray_t *da;

   da = META( a );
   da->length   = len;
   newcap       = pow2up( len );
   if( da->capacity != newcap )
   {  da = adjust( da, da->size, newcap );
      if( da != NULL ) a = (char*)da + OFS;
      else             a = NULL;
   }
   return a;
}

void* addemp( struct dynarray_t* da, void ** data )
{  void*    a;
   unsigned dataofs;

   a = NULL;
   dataofs = da->size * da->length;
   da->length++;
   if( da->length > da->capacity )
   {  da->capacity <<= 1;
      da = adjust( da, da->size, da->capacity );
   }
   if( da != NULL )
   {  a     = (char*)da + OFS;
      *data = (char*)a  + dataofs;
   }
   return a;
}

void* da_addemp( void * a, void ** data )
{  return addemp( META( a ), data );  }

void* da_add( void * a, void * data )
{  unsigned int        size;
   void*               addr;
   struct dynarray_t  *da;

   da = META(a);
   size = da->size;
   a = addemp( da, &addr );
   if( a != NULL ) memcpy( addr, data, size );
   return a;
}

void da_free( void * a )
{  free( META( a ) );  }

int da_len( void * a )
{  return META( a )->length;  }

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

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


#138122

Fromjadill33@gmail.com
Date2018-11-19 08:44 -0800
Message-ID<c4a74084-d505-41c9-8ea8-4a0ca2f3fc6d@googlegroups.com>
In reply to#138077
On Saturday, November 17, 2018 at 6:38:29 AM UTC-5, Anton Shepelev wrote:
> By way of exercise, I am writing a small dynamic array
> library that makes dynamic arrays appear and behave as if
> they were pointers to allocated objects of the corresponding
> type, so that they can be substituded for such pointers
> without rewriting the code.  The following sample (without
> error handling for simplicity):
> 
>    #include <stdio.h>
>    #include <stdlib.h>
>    #include <string.h>
>    #include "dynarray.h"
>    /* ... */
>    int *a, v, i, l;
>    void* vP;
> 
>    da_new ( &a, sizeof( int ) );
> 
>    da_setlen( &a, 2 );
>    a[0] = 0;
>    a[1] = 1;
> 
>    da_setlen( &a, 4 );
>    a[2] = 2;
>    a[3] = 3;
> 
>    v = 4;
>    da_add( &a, &v );
> 
>    v = 5;
>    da_addemp( &a, &vP );
>    memcpy( vP, &v, sizeof( int ) );
> 
>    l = da_len( &a );
>    for( i = 0; i < l; i++ )
>    {  printf("%i ", a[i]);  }
> 
>    da_free( &a );
> 
> prints: "0 1 2 3 4 5 ", but in order to make sure that my
> implementation works not by coincidence but by design, I
> need a better understanding of alignment, which the Standard
> defines as:
> 
>    requirement that objects of a particular type be located
>    on storage boundaries with addresses that are particular
>    multiples of a byte address.
> 
> Futher it mentions "alignment requirements" but never gives
> any.  What, for example, may be the alignment requirements
> for the types `char' and `pointer to char'?
> 
> On pointers --
> 
>    A pointer to void shall have the same representation and
>    alignment requirements as a pointer to a character type.
>    Similarly, pointers to qualified or unqualified versions
>    of compatible types shall have the same representation
>    and alignment requirements.
>    [...]
>    A pointer to an object or incomplete type may be
>    converted to a pointer to a different object or
>    incomplete type. If the resulting pointer is not
>    correctly aligned for the pointed-to type, the behavior
>    is undefined.
> 
> How may one know whether a char pointer is "correctly
> aligned for" int?  Can one, for example, take an int* and
> read it byte-by-byte through a pointer to char* converted
> from the int pointer?
> 
> How does malloc() work --
> 
>    The pointer returned if the allocation succeeds is
>    suitably aligned so that it may be assigned to a pointer
>    to any type of object and then used to access such an
>    object or an array of such objects
> 
> Is not such an assignment, in terms of the standard, a
> conversion of one pointer type to another?  And if so, does
> not it imply that void pointers (and therefore char
> pointers) are somehow "correctly aligned for" any pointed-to
> type, whatever that means?  Notice that the sentence above
> says nothing the about the alignment of the actual allocated
> object created upon successful invocation of malloc().  Why
> does it not matter?  I suspected that calloc() performed
> some alignment based on its `size' parameter, but I was
> wrong.
> 
> If the alignment of a pointer is, by definition above, its
> location on storage boundaries, then what does it have to do
> with access to the pointed-to alocated objects?  If not,
> then where is pointer alignment defined, perhaps with
> respect to a pointed-to type?

If you're looking at making "fat" pointers to your array, you'll need to
depend on a max_align_t or ALIGN_MAX of some kind so that your data and your
structure are aligned to that value.

Take for example a simple "fat" pointer where you want to store the size
of the allocation.  You are guaranteed by the standard that malloc provides
an address that is maximally aligned for any type by the implementation.  If
you do the naïve approach where you attach a sizeof type to the data, your
array won't be aligned for types whose alignment is > size_t.

void* track_malloc( size_t size )
{
  void* p = NULL;
  void* mem;

  mem = malloc( sizeof (size_t) + size );

  if ( mem )
  {
    *((size_t*)mem) = size;
    p = (unsigned char*)mem + sizeof (size_t);
  }

  return p;
}

    ---------- --------------------
   |  size_t  |       object       |
    ---------- --------------------
   /          /
mem          p

When it comes time to free the object, one needs to factor in the
attached 'size_t' object and free the entire memory block.

void track_free( void* p )
{
  void* mem;
  if ( p )
  {
    mem = (unsigned char*)p - sizeof (size_t);
    free( mem );
  }
}

On my computer, alignment of size_t is 4, and double is 8, so this strategy
will fail to properly access memory of a double allocated array.

However, if you know the max_align_t size for your system, you can allocate
integer multiples of that value and place the data at that offset.

#define c_maxalign_sizeof(type) ( c_align_size( sizeof (type), ALIGN_MAX ) )

            c_maxalign_sizeof example
 -----------------------------------------------
|       type       | sizeof | c_maxalign_sizeof |
 -----------------------------------------------
  char               1        8
  short int          2        8
  int                4        8
  long int           4        8
  long long int      8        8
  float              4        8
  double             8        8
  long double        12       16
  size_t             4        8
  ptrdiff_t          4        8
  void*              4        8
  struct c_timeval   16       16
  struct c_list      12       16
  struct c_array     28       32

ALIGN_MAX = 8

This is output from my sample program.  It depends on c_align_size and
ALIGN_MAX.  Chris Thomasson has some wizardry to get that value based on
using an 'alignof' macro based on 'offsetof' and a union with a wide
enough selection of types to get all the possible combinations of types
with different alignments.  C2011 makes it much easier.

c_align_size is a simple function that takes a size and rounds it to a
multiple of a specified alignment.

size_t c_align_size( size_t size, size_t alignment );

 ------------------------------------------
| Alignment |     Range     | Aligned Size |
 ------------------------------------------
  4           1-4             4
              5-8             8
              9-12            12
              13-16           16
              17-20           20
              21-24           24
              25-28           28
              29-32           32
              33-36           36
              37-40           40
              41-44           44
              45-48           48
              49-52           52
              53-56           56
              57-60           60
              61-64           64

  8           1-8             8
              9-16            16
              17-24           24
              25-32           32
              33-40           40
              41-48           48
              49-56           56
              57-64           64

  16          1-16            16
              17-32           32
              33-48           48
              49-64           64

  64          1-64            64

With this in place, you can replace your special malloc functions with

    p = (unsigned char*)mem + c_maxalign_sizeof (size_t);
    mem = (unsigned char*)p - c_maxalign_sizeof (size_t);

Then you can make your structure as large as you want and it should work
at least on non-exotic systems.

Best regards,
John D.

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


#138131

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-20 00:02 +0300
Message-ID<20181120000227.bd5d6bdc9d0afe69fdbef1af@gmail.com>
In reply to#138122
Thank you for the reply, jadill33:

> If you're looking at making "fat" pointers to your array,
> you'll need to depend on a max_align_t or ALIGN_MAX of
> some kind so that your data and your structure are aligned
> to that value.

Not even in C99.

> Take for example a simple "fat" pointer where you want to
> store the size of the allocation.  You are guaranteed by
> the standard that malloc provides an address that is
> maximally aligned for any type by the implementation.  If
> you do the naive approach where you attach a sizeof type
> to the data, your array won't be aligned for types whose
> alignment is > size_t.

Sounds logical, but I fail to see how it is formally true of
the standard, which seems to allow types of the same size to
have different alignments...

> void* track_malloc( size_t size )
> {
>   void* p = NULL;
>   void* mem;
>
>   mem = malloc( sizeof (size_t) + size );
>
>   if ( mem )
>   {
>     *((size_t*)mem) = size;
>     p = (unsigned char*)mem + sizeof (size_t);
>   }
>
>   return p;
> }
>
>     ---------- --------------------
>    |  size_t  |       object       |
>     ---------- --------------------
>    /          /
> mem          p
>
> When it comes time to free the object, one needs to factor in the
> attached 'size_t' object and free the entire memory block.
>
> void track_free( void* p )
> {
>   void* mem;
>   if ( p )
>   {
>     mem = (unsigned char*)p - sizeof (size_t);
>     free( mem );
>   }
> }

That is basically what I do too.

> However, if you know the max_align_t size for your system, you can allocate
> integer multiples of that value and place the data at that offset.
>
> #define c_maxalign_sizeof(type) ( c_align_size( sizeof (type), ALIGN_MAX ) )
>
>             c_maxalign_sizeof example
>  -----------------------------------------------
> |       type       | sizeof | c_maxalign_sizeof |
>  -----------------------------------------------
>   char               1        8
>   short int          2        8
>   int                4        8
>   long int           4        8
>   long long int      8        8
>   float              4        8
>   double             8        8
>   long double        12       16
>   size_t             4        8
>   ptrdiff_t          4        8
>   void*              4        8
>   struct c_timeval   16       16
>   struct c_list      12       16
>   struct c_array     28       32
>
> ALIGN_MAX = 8
>
> This is output from my sample program.  It depends on c_align_size and
> ALIGN_MAX.

Does it meant that int's occupy four bytes in memory yet
must be aligned to eight bytes?  You must have a 64-bit
system and compiler, right?

> Chris Thomasson has some wizardry to get that value based
> on using an 'alignof' macro based on 'offsetof' and a
> union with a wide enough selection of types to get all the
> possible combinations of types with different alignments.

Is not another option to expose the array constructor as a
macro taking the element type as an argument and calcuating
the alignment with

  #define alignmentof(type) offsetof(struct { char c;type t;},t)

> c_align_size is a simple function that takes a size and
> rounds it to a multiple of a specified alignment.
> [...]  With this in place, you can replace your special
> malloc functions with
>
> p   = (unsigned char*)mem + c_maxalign_sizeof (size_t);
> mem = (unsigned char*)p   - c_maxalign_sizeof (size_t);

Why do you use unsigned char instead of char?  Why do you
pass to c_maxalign_sizeof size_t instead of the type of the
array element?

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

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


#138135

FromKeith Thompson <kst-u@mib.org>
Date2018-11-19 13:51 -0800
Message-ID<lnin0srb10.fsf@kst-u.example.com>
In reply to#138131
Anton Shepelev <anton.txt@gmail.com> writes:
> Thank you for the reply, jadill33:
[...]
>> However, if you know the max_align_t size for your system, you can allocate
>> integer multiples of that value and place the data at that offset.
>>
>> #define c_maxalign_sizeof(type) ( c_align_size( sizeof (type), ALIGN_MAX ) )
>>
>>             c_maxalign_sizeof example
>>  -----------------------------------------------
>> |       type       | sizeof | c_maxalign_sizeof |
>>  -----------------------------------------------
>>   char               1        8
>>   short int          2        8
>>   int                4        8
>>   long int           4        8
>>   long long int      8        8
>>   float              4        8
>>   double             8        8
>>   long double        12       16
>>   size_t             4        8
>>   ptrdiff_t          4        8
>>   void*              4        8
>>   struct c_timeval   16       16
>>   struct c_list      12       16
>>   struct c_array     28       32
>>
>> ALIGN_MAX = 8
>>
>> This is output from my sample program.  It depends on c_align_size and
>> ALIGN_MAX.
>
> Does it meant that int's occupy four bytes in memory yet
> must be aligned to eight bytes?  You must have a 64-bit
> system and compiler, right?

I hope it doesn't mean that.  If it does, it's wrong.  A type cannot
have an alignment larger than its size.  There are no gaps between array
elements, which implies that int cannot have a size of 4 bytes and an
alignment of 8 bytes.

[...]

-- 
Keith Thompson (The_Other_Keith) kst@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#138137

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-11-20 01:08 +0300
Message-ID<20181120010851.0c14136ff5c4801c9966a234@gmail.com>
In reply to#138135
Keith Thompson to Anton Shepelev:

> > jadill33:
> >
> > >             c_maxalign_sizeof example
> > >  -----------------------------------------------
> > > |       type       | sizeof | c_maxalign_sizeof |
> > >  -----------------------------------------------
> > >   char               1        8
> > >   short int          2        8
> > >   int                4        8
> > >   long int           4        8
> > >   long long int      8        8
> > >   float              4        8
> > >   double             8        8
> > >   long double        12       16
> > >   size_t             4        8
> > >   ptrdiff_t          4        8
> > >   void*              4        8
> > >   struct c_timeval   16       16
> > >   struct c_list      12       16
> > >   struct c_array     28       32
> > >
> > > ALIGN_MAX = 8
> >
> > Does it meant that int's occupy four bytes in memory yet
> > must be aligned to eight bytes?  You must have a 64-bit
> > system and compiler, right?
>
> I hope it doesn't mean that.  If it does, it's wrong.  A
> type cannot have an alignment larger than its size.  There
> are no gaps between array elements, which implies that int
> cannot have a size of 4 bytes and an alignment of 8 bytes.

I thouth the start of the array should be at a multiple of
eight.  If not so, then c_maxalign_sizeof must denote not
the actual alignment, but the one certainly sufficient for
that type (providing all possible alignments are powers of
two).  ALIGN_MAX is acutally the minimum alignment (so that
all per-type sufficient alignments are its binary
multiples).  How do I find that out?

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

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


#138140

Fromjameskuyper@alumni.caltech.edu
Date2018-11-19 14:31 -0800
Message-ID<18218714-06ee-4835-9cb1-d4a63175b0a9@googlegroups.com>
In reply to#138137
On Monday, November 19, 2018 at 5:08:59 PM UTC-5, Anton Shepelev wrote:
...
> I thouth the start of the array should be at a multiple of
> eight.

Was that an arbitrary choice, or did you have a specific reason for it?

> ...  If not so, then c_maxalign_sizeof must denote not
> the actual alignment, but the one certainly sufficient for
> that type (providing all possible alignments are powers of
> two).  ALIGN_MAX is acutally the minimum alignment (so that
> all per-type sufficient alignments are its binary
> multiples).  How do I find that out?

In C2011, you can use _Alignof(max_align_t) to find the maximum
alignment requiredment, but the only mechanism for finding the minimum
alignment requirement that is greater than 1 is the same inconvenient
one that applies all earlier versions of C: read the documentation of
the implementation you are targeting your code at.

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


#138151

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-20 15:21 +0300
Message-ID<20181120152137.055c20b5117a72f6e81377fb@g{oogle}mail.com>
In reply to#138140
James Kuyper to Anton Shepelev:

>>jadill33:
>>
>>>            c_maxalign_sizeof example
>>> -----------------------------------------------
>>>|       type       | sizeof | c_maxalign_sizeof |
>>> -----------------------------------------------
>>>  ...                ...      ...
>>>  int                4        8
>>
>>I thouth [thought] the start of the array should be at a
>>multiple of eight.
>
>Was that an arbitrary choice, or did you have a specific
>reason for it?

It was my incorrect interpretation of jadill33's data: that
although a type can't have an alignment wider than its size,
that may be required about the starting address of an
allocated array.  Please, ignore it.  I still don't know the
correct interpretation.

>In C2011, you can use _Alignof(max_align_t) to find the
>maximum alignment requiredment, but the only mechanism for
>finding the minimum alignment requirement that is greater
>than 1 is the same inconvenient one that applies all
>earlier versions of C: read the documentation of the
>implementation you are targeting your code at.

What about the method Chris M. Thomasson's uses:

   #define alignmentof(type) offsetof(struct { char c;type t;},t)

Is the result of this macro connected with the alignment of
type t in any way?

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

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


#138155

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2018-11-20 08:59 -0500
Message-ID<pt140j$dsi$1@dont-email.me>
In reply to#138151
On 11/20/18 07:21, Anton Shepelev wrote:
> James Kuyper to Anton Shepelev:
> 
>>> jadill33:
>>>
>>>>            c_maxalign_sizeof example
>>>> -----------------------------------------------
>>>> |       type       | sizeof | c_maxalign_sizeof |
>>>> -----------------------------------------------
>>>>  ...                ...      ...
>>>>  int                4        8
>>>
>>> I thouth [thought] the start of the array should be at a
>>> multiple of eight.
>>
>> Was that an arbitrary choice, or did you have a specific
>> reason for it?
> 
> It was my incorrect interpretation of jadill33's data: that
> although a type can't have an alignment wider than its size,
> that may be required about the starting address of an
> allocated array.  Please, ignore it.  I still don't know the
> correct interpretation.

I believe it's permitted for arrays of a given element type to have an
alignment requirement that is an integer multiple, greater than 1, of
the element type's alignment requirement.
However, it's not possible for any object, not even an array, to have an
alignment requirement that is larger than the object's size. The size of
an object must be an integer multiple of the object's alignment
requirement - otherwise arrays of that object type would have to have
padding between the elements, which is prohibited.

In any event, all of this implementation-specific; an implementation
with all of the characteristics specified by jadill3 might or might not
impose higher requirements on the alignment of an array, and could still
be fully conforming either way.

jadill3 was actually going the other way: he's not saying that MAX_ALIGN
is required for any particular data type, merely that it's guaranteed to
be sufficient. His approach might result in wasted space due to the data
array being aligned more strictly than would be needed for some types.

>> In C2011, you can use _Alignof(max_align_t) to find the
>> maximum alignment requiredment, but the only mechanism for
>> finding the minimum alignment requirement that is greater
>> than 1 is the same inconvenient one that applies all
>> earlier versions of C: read the documentation of the
>> implementation you are targeting your code at.
> 
> What about the method Chris M. Thomasson's uses:
> 
>    #define alignmentof(type) offsetof(struct { char c;type t;},t)
> 
> Is the result of this macro connected with the alignment of
> type t in any way?

It's guaranteed to give a result that is an integer multiple of the
alignment requirement, and on any reasonable implementation that
multiple should be 1, but it's not guaranteed to be 1.

But you can't use this fact to determine the minimum alignment
requirement that's greater than 1, over all types.
The main reason this is true is that there's infinitely many different
types you can name in a C program that might have different alignment
requirements. There's no way to write code that's guaranteed to cover
the one that has the smallest such requirement.
It's worse than that, however. C allows an implementation to support
extended integer types. It could be the case that the smallest alignment
requirement greater than 1 comes up only for types that involve one of
the extended integer types that is NOT used by the implementation for
any of the standard typedefs, so there's no way to name such a type in
strictly conforming C code.

This is the same argument, in reverse, as to why you couldn't use this
method to determine the maximum alignment requirement.

Note: it's not quite clear to me why you're interested in the minimum
alignment requirement. Perhaps I been misinterpreting something you said
earlier?

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


#138159

FromKeith Thompson <kst-u@mib.org>
Date2018-11-20 11:06 -0800
Message-ID<ln5zwrr2k4.fsf@kst-u.example.com>
In reply to#138155
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[...]
> I believe it's permitted for arrays of a given element type to have an
> alignment requirement that is an integer multiple, greater than 1, of
> the element type's alignment requirement.
> However, it's not possible for any object, not even an array, to have an
> alignment requirement that is larger than the object's size. The size of
> an object must be an integer multiple of the object's alignment
> requirement - otherwise arrays of that object type would have to have
> padding between the elements, which is prohibited.
[...]

It's certainly possible for an implementation to *choose* to allocate an
array object at a stricter alignment than that of its element type, but
I don't think it can require such an alignment.

To take a concrete example, suppose int is 4 bytes with a 4-byte
alignment requirement.  Given:
    int arr[8];
either arr[0] or arr[1] can be the start of an int[2] object.
(But some operations might be faster if arr is aligned to 8 or even
16 bytes.)

(Proving this from the normative wording of the standard is left as an
exercise.)

-- 
Keith Thompson (The_Other_Keith) kst@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#138161

Fromjameskuyper@alumni.caltech.edu
Date2018-11-20 12:43 -0800
Message-ID<183c3263-1111-47b8-9a8d-ecb66aec5358@googlegroups.com>
In reply to#138159
On Tuesday, November 20, 2018 at 2:07:04 PM UTC-5, Keith Thompson wrote:
> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
> [...]
> > I believe it's permitted for arrays of a given element type to have an
> > alignment requirement that is an integer multiple, greater than 1, of
> > the element type's alignment requirement.
> > However, it's not possible for any object, not even an array, to have an
> > alignment requirement that is larger than the object's size. The size of
> > an object must be an integer multiple of the object's alignment
> > requirement - otherwise arrays of that object type would have to have
> > padding between the elements, which is prohibited.
> [...]
> 
> It's certainly possible for an implementation to *choose* to allocate an
> array object at a stricter alignment than that of its element type, but
> I don't think it can require such an alignment.
> 
> To take a concrete example, suppose int is 4 bytes with a 4-byte
> alignment requirement.  Given:
>     int arr[8];
> either arr[0] or arr[1] can be the start of an int[2] object.
> (But some operations might be faster if arr is aligned to 8 or even
> 16 bytes.)
> 
> (Proving this from the normative wording of the standard is left as an
> exercise.)

There have been discussions that I participated in of the idea that, to
use your example, int[2] might have an alignment requirement of 8 rather
than 4. This is indistinguishable from what you describe for stand-alone
arrays. However, for arrays that are  members of structs, it could be
more meaningful. I seem to remember this being addressed in the
resolution of a DR, but I don't remember which DR, and I'm not sure what
the resolution was, and I'm not sure how to set up a search for such
discussions.

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


#138165

FromKeith Thompson <kst-u@mib.org>
Date2018-11-20 14:33 -0800
Message-ID<ln1s7fqszq.fsf@kst-u.example.com>
In reply to#138161
jameskuyper@alumni.caltech.edu writes:
> On Tuesday, November 20, 2018 at 2:07:04 PM UTC-5, Keith Thompson wrote:
>> James Kuyper <jameskuyper@alumni.caltech.edu> writes:
>> [...]
>> > I believe it's permitted for arrays of a given element type to have an
>> > alignment requirement that is an integer multiple, greater than 1, of
>> > the element type's alignment requirement.
>> > However, it's not possible for any object, not even an array, to have an
>> > alignment requirement that is larger than the object's size. The size of
>> > an object must be an integer multiple of the object's alignment
>> > requirement - otherwise arrays of that object type would have to have
>> > padding between the elements, which is prohibited.
>> [...]
>> 
>> It's certainly possible for an implementation to *choose* to allocate an
>> array object at a stricter alignment than that of its element type, but
>> I don't think it can require such an alignment.
>> 
>> To take a concrete example, suppose int is 4 bytes with a 4-byte
>> alignment requirement.  Given:
>>     int arr[8];
>> either arr[0] or arr[1] can be the start of an int[2] object.
>> (But some operations might be faster if arr is aligned to 8 or even
>> 16 bytes.)
>> 
>> (Proving this from the normative wording of the standard is left as an
>> exercise.)
>
> There have been discussions that I participated in of the idea that, to
> use your example, int[2] might have an alignment requirement of 8 rather
> than 4. This is indistinguishable from what you describe for stand-alone
> arrays. However, for arrays that are  members of structs, it could be
> more meaningful. I seem to remember this being addressed in the
> resolution of a DR, but I don't remember which DR, and I'm not sure what
> the resolution was, and I'm not sure how to set up a search for such
> discussions.

This program assumes that an array type cannot have a stricter
required alignment than its element type.  I haven't been able to
prove that from the standard.  The program would have undefined
behavior on an implementation on which int[2] has a stricter
alignment requirement than int.  (I would expect this program to
behave as expected under any "reasonable" implementation.)

Thoughts?

    #include <stdio.h>

    typedef int int2[2];

    static void show(int2 *ptr) {
        printf("%d %d\n", (*ptr)[0], (*ptr)[1]);
    }

    int main(void) {
        int arr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
        show((int2*)&arr[0]);
        show((int2*)&arr[1]);
    }

-- 
Keith Thompson (The_Other_Keith) kst@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#138168

FromAnton Shepelev <anton.txt@g{oogle}mail.com>
Date2018-11-21 14:33 +0300
Message-ID<20181121143342.622b420e069743d4f2f1caeb@g{oogle}mail.com>
In reply to#138165
Keith Thompson:

>    #include <stdio.h>
>
>    typedef int int2[2];
>
>    static void show(int2 *ptr) {
>        printf("%d %d0, (*ptr)[0], (*ptr)[1]);
>    }
>
>    int main(void) {
>        int arr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
>        show((int2*)&arr[0]);
>        show((int2*)&arr[1]);
>    }

The effective type of the &arr[0] access is `pointer to
int', whereas you convert it into a pointer to an array of
two int values.  Is not this pointer conversion UB?  Even if
it successds, won't the accesses in show() violate aliasing?

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

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


#138171

FromRichard Damon <Richard@Damon-Family.org>
Date2018-11-21 07:49 -0500
Message-ID<TvcJD.314885$nH2.239239@fx26.iad>
In reply to#138168
On 11/21/18 6:33 AM, Anton Shepelev wrote:
> Keith Thompson:
> 
>>    #include <stdio.h>
>>
>>    typedef int int2[2];
>>
>>    static void show(int2 *ptr) {
>>        printf("%d %d0, (*ptr)[0], (*ptr)[1]);
>>    }
>>
>>    int main(void) {
>>        int arr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
>>        show((int2*)&arr[0]);
>>        show((int2*)&arr[1]);
>>    }
> 
> The effective type of the &arr[0] access is `pointer to
> int', whereas you convert it into a pointer to an array of
> two int values.  Is not this pointer conversion UB?  Even if
> it successds, won't the accesses in show() violate aliasing?
> 

My understanding is that in C you rarely actually access an object of
array type. All the accesses to the elements of arr are to object of
type int, so we had no aliasing there.

We did create some temporary object of type pointer to int, and then
converted them to pointer to array of int and placed that value in a new
object (so no aliasing). The standard defines that the conversion
between pointer to array of object and pointer to same object type is
safe (and in that direction even happens automatically). I believe there
is even comments that the direction of pointer to object to pointer to
array of objects is safe as there is an explicit statement that even for
a single object, a pointer to it can be converted to a pointer to array
of one element of that object.

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


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

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


csiph-web