Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #138077 > unrolled thread
| Started by | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| First post | 2018-11-17 14:38 +0300 |
| Last post | 2018-11-19 14:33 -0800 |
| Articles | 20 on this page of 134 — 18 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Anton Shepelev <anton.txt@g{oogle}mail.com> |
|---|---|
| Date | 2018-11-19 16:04 +0300 |
| Subject | Re: 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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2018-11-19 14:56 +0000 |
| Subject | Re: 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]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2018-11-24 19:24 +0300 |
| Subject | Re: 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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2018-11-24 21:31 +0000 |
| Subject | Re: 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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2018-11-24 21:46 +0000 |
| Subject | Re: 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]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2018-11-25 01:12 +0300 |
| Subject | Re: 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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2018-11-25 01:39 +0000 |
| Subject | Re: 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]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2018-11-25 14:19 +0300 |
| Subject | Re: 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]
| From | jadill33@gmail.com |
|---|---|
| Date | 2018-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]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2018-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-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]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2018-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]
| From | jameskuyper@alumni.caltech.edu |
|---|---|
| Date | 2018-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]
| From | Anton Shepelev <anton.txt@g{oogle}mail.com> |
|---|---|
| Date | 2018-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2018-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-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]
| From | jameskuyper@alumni.caltech.edu |
|---|---|
| Date | 2018-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-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]
| From | Anton Shepelev <anton.txt@g{oogle}mail.com> |
|---|---|
| Date | 2018-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-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