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


Groups > comp.lang.c.moderated > #462 > unrolled thread

Portable/strictly conforming alternative to the "struct hack" (?)

Started byÁrpád Goretity <arpad.goretity@gmail.com>
First post2013-09-02 04:08 -0500
Last post2013-10-08 16:38 -0500
Articles 5 — 3 participants

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


Contents

  Portable/strictly conforming alternative to the "struct hack" (?) Árpád Goretity <arpad.goretity@gmail.com> - 2013-09-02 04:08 -0500
    Re: Portable/strictly conforming alternative to the "struct hack" (?) Jasen Betts <jasen@xnet.co.nz> - 2013-09-06 23:24 -0500
      Re: Portable/strictly conforming alternative to the "struct hack" (?) Jasen Betts <jasen@xnet.co.nz> - 2013-09-11 17:26 -0500
        Re: Portable/strictly conforming alternative to the "struct hack" (?) Árpád Goretity <arpad.goretity@gmail.com> - 2013-10-03 13:37 -0500
          Re: Portable/strictly conforming alternative to the "struct hack" (?) Keith Thompson <kst-u@mib.org> - 2013-10-08 16:38 -0500

#462 — Portable/strictly conforming alternative to the "struct hack" (?)

FromÁrpád Goretity <arpad.goretity@gmail.com>
Date2013-09-02 04:08 -0500
SubjectPortable/strictly conforming alternative to the "struct hack" (?)
Message-ID<clcm-20130902-0003@plethora.net>
I believe I've found a way to achieve something like the well-known "struct hack". I'm curoius if this strictly conforms to C89/C90 (I'm writing a library and my goal is full, strict C89/C90 conformance.)

The main idea is: I allocate memory large enough to hold an initial struct and the elements of the array. The exact size is (K + N) * sizeof(array_base_type), where `K` is  large enough so that `K * sizeof(array_base_type) >= sizeof(the_struct)`, and `N` is the number of array elements.

Then, I use the pointer that `malloc()` returned to store `the_struct`, then I use pointer arithmetic to obtain a pointer to the beginning of an array of `N` elements of the array following the struct.

One line of code is worth more than a thousand words, so here is an implementation:

    typedef struct Header {
        size_t length;
        /* other members follow */
    } Header;

    typedef struct Value {
        int type;
        union {
            int intval;
            double fltval;
        } v;
    } Value;

    /* round up to nearest multiple of sizeof(Value) so that a Header struct fits in */
    size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value);

    size_t n_arr = /* arbitrary array size here */;
    void *frame = malloc((n_hdr + n_arr) * sizeof(Value));

    Header *hdr = frame;
    Value *stack_bottom = (Value *)frame + n_hdr;

My main concern is that the last two assignments (using `frame` as both a pointer to Header and a pointer to Value) may violate the strict aliasing rule. I do not, however, dereference `hdr` as a pointer to Value - it's only pointer arithmetic that is performed on `frame` in order to access the first element of the value array, so I don't effectively access *the same* object using pointers of different types.

So, is this approach any better than the classic struct hack (which has been officially deemed UB), or is it UB too?
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line.  Sorry.

[toc] | [next] | [standalone]


#464

FromJasen Betts <jasen@xnet.co.nz>
Date2013-09-06 23:24 -0500
Message-ID<clcm-20130906-0001@plethora.net>
In reply to#462
On 2013-09-02, Árpád Goretity <arpad.goretity@gmail.com> wrote:
> I believe I've found a way to achieve something like the well-known "struct hack". I'm curoius if this strictly conforms to C89/C90 (I'm writing a library and my goal is full, strict C89/C90 conformance.)
>
> The main idea is: I allocate memory large enough to hold an initial struct and the elements of the array. The exact size is (K + N) * sizeof(array_base_type), where `K` is  large enough so that `K * sizeof(array_base_type) >= sizeof(the_struct)`, and `N` is the number of array elements.
>
> Then, I use the pointer that `malloc()` returned to store `the_struct`, then I use pointer arithmetic to obtain a pointer to the beginning of an array of `N` elements of the array following the struct.
>
> One line of code is worth more than a thousand words, so here is an implementation:
>
>     typedef struct Header {
>         size_t length;
>         /* other members follow */
>     } Header;

strange....

>     typedef struct Value {
>         int type;
>         union {
>             int intval;
>             double fltval;
>         } v;
>     } Value;
>
>     /* round up to nearest multiple of sizeof(Value) so that a Header struct fits in */

>     size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value);

that n_hdr expression looks kind of dodgy, basically it evaluates to 1, 
anyone who goes to such lengths to caclulate 1 is unlikley to have
discovered something special. After that  I stopped trying to understand 
your code

> So, is this approach any better than the classic struct hack (which has been officially deemed UB), or is it UB too?

Look at modern C compilers ...
this has been perfectly valid, well-behaved C since the 1999 standard:

struct clump {
    int      thing ;
    sometype data[];
	}

-- ⚂⚃ 100% natural

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line.  Sorry.

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


#470

FromJasen Betts <jasen@xnet.co.nz>
Date2013-09-11 17:26 -0500
Message-ID<clcm-20130911-0001@plethora.net>
In reply to#464
On 2013-09-07, Jasen Betts <jasen@xnet.co.nz> wrote:
> On 2013-09-02, Árpád Goretity <arpad.goretity@gmail.com> wrote:

>>     typedef struct Header {
>>         size_t length;
>>         /* other members follow */
>>     } Header;

>>     size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value);
>
> that n_hdr expression looks kind of dodgy, basically it evaluates to 1, 
> anyone who goes to such lengths to caclulate 1 is unlikley to have
> discovered something special. After that  I stopped trying to understand 
> your code

I am of course wrong - having ignored the "/* other members follow */"
comment. sorry.


-- 
⚂⚃ 100% natural

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line.  Sorry.

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


#484

FromÁrpád Goretity <arpad.goretity@gmail.com>
Date2013-10-03 13:37 -0500
Message-ID<clcm-20131003-0001@plethora.net>
In reply to#470
> anyone who goes to such lengths to caclulate 1 is unlikley to have 
discovered something special

Don't insult me.

> that n_hdr expression looks kind of dodgy, basically it evaluates to 1,

How do you know?

> Look at modern C compilers ... 
this has been perfectly valid, well-behaved C since the 1999 standard: 

Again, I don't like being like an uninformed moron. I know we have C99. I just want to support Visual "Crappy" studio which doesn't. Hence I can't use C99. That's all.
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line.  Sorry.

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


#514

FromKeith Thompson <kst-u@mib.org>
Date2013-10-08 16:38 -0500
Message-ID<clcm-20131008-0003@plethora.net>
In reply to#484
Árpád Goretity <arpad.goretity@gmail.com> writes:
>> anyone who goes to such lengths to caclulate 1 is unlikley to have 
> discovered something special
>
> Don't insult me.
>
>> that n_hdr expression looks kind of dodgy, basically it evaluates to 1,
>
> How do you know?
>
>> Look at modern C compilers ... 
> this has been perfectly valid, well-behaved C since the 1999 standard: 
>
> Again, I don't like being like an uninformed moron. I know we have
> C99. I just want to support Visual "Crappy" studio which
> doesn't. Hence I can't use C99. That's all.

When you post a followup, your newsreader should automatically
insert an attribution line, so that readers can tell who wrote what.
Please don't delete it.

You quote an article posted by Jasen Betts on September 6, but the
headers indicate that you replied to another article that he posted
on September 11, in which Jasen wrote:

| I am of course wrong - having ignored the "/* other members follow */"
| comment. sorry.

It's possible you didn't see that; this is a moderated group, which can
do funny things with headers and message-ids (and I'm too lazy to track
it down further).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
-- 
comp.lang.c.moderated - moderation address: clcm@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line.  Sorry.

[toc] | [prev] | [standalone]


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


csiph-web