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


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

Help on this typedef

Started byfl <rxjwg98@gmail.com>
First post2017-05-10 19:12 -0700
Last post2017-05-27 06:15 -0700
Articles 20 on this page of 68 — 16 participants

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


Contents

  Help on this typedef fl <rxjwg98@gmail.com> - 2017-05-10 19:12 -0700
    Re: Help on this typedef Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-05-10 21:06 -0600
    Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-10 20:11 -0700
      Re: Help on this typedef David Brown <david.brown@hesbynett.no> - 2017-05-11 10:03 +0200
        Re: Help on this typedef supercat@casperkitty.com - 2017-05-11 08:35 -0700
          Re: Help on this typedef David Brown <david.brown@hesbynett.no> - 2017-05-12 10:34 +0200
            Re: Help on this typedef joel.rees@gmail.com - 2017-05-12 06:01 -0700
            Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-12 09:38 -0700
          Re: Help on this typedef joel.rees@gmail.com - 2017-05-12 05:08 -0700
            Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-13 14:25 -0700
              Re: Help on this typedef joel.rees@gmail.com - 2017-05-14 23:36 -0700
                Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-15 07:23 -0700
                  Re: Help on this typedef joel.rees@gmail.com - 2017-05-18 07:40 -0700
                    Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-18 09:35 -0700
                      Re: Help on this typedef supercat@casperkitty.com - 2017-05-18 10:59 -0700
                      Re: Help on this typedef joel.rees@gmail.com - 2017-05-18 23:40 -0700
                        Re: Help on this typedef jadill33@gmail.com - 2017-05-19 08:12 -0700
                          Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 08:41 -0700
                            Re: Help on this typedef jadill33@gmail.com - 2017-05-19 09:41 -0700
                        Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-19 09:34 -0700
                          Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 10:18 -0700
                          Re: Help on this typedef Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-19 21:35 +0100
                            Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 14:16 -0700
                            Re: Help on this typedef Ike Naar <ike@iceland.freeshell.org> - 2017-05-19 21:15 +0000
                              Re: Help on this typedef Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-19 23:54 +0100
                            Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-19 14:25 -0700
                              Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 15:18 -0700
                              Re: Help on this typedef Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-19 23:52 +0100
                                Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-19 16:42 -0700
                                  Re: Help on this typedef Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-20 01:16 +0100
                            Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-20 01:58 -0700
                              Re: Help on this typedef joel.rees@gmail.com - 2017-05-20 02:25 -0700
                          Re: Help on this typedef joel.rees@gmail.com - 2017-05-19 22:09 -0700
                            Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 23:23 -0700
                        Re: Help on this typedef "James R. Kuyper" <jameskuyper@verizon.net> - 2017-05-19 13:33 -0400
                          Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 13:44 -0700
                            Re: Help on this typedef jameskuyper@verizon.net - 2017-05-19 19:20 -0700
                              Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 23:30 -0700
                                Re: Help on this typedef jameskuyper@verizon.net - 2017-05-20 07:20 -0700
                                Re: Help on this typedef jameskuyper@verizon.net - 2017-05-20 07:46 -0700
                                  Re: Help on this typedef supercat@casperkitty.com - 2017-05-22 10:50 -0700
                    Re: Help on this typedef "James R. Kuyper" <jameskuyper@verizon.net> - 2017-05-18 12:37 -0400
                    Re: Help on this typedef Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-18 20:02 +0100
                      Re: Help on this typedef joel.rees@gmail.com - 2017-05-19 00:20 -0700
                        Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-19 09:51 -0700
                          Re: Help on this typedef supercat@casperkitty.com - 2017-05-19 10:31 -0700
                    Re: Help on this typedef Ike Naar <ike@iceland.freeshell.org> - 2017-05-19 19:48 +0000
                    Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-20 08:47 -0700
          Re: Help on this typedef "Patrick.Schluter" <Patrick.Schluter@free.fr> - 2017-05-27 18:50 +0200
    Re: Help on this typedef joel.rees@gmail.com - 2017-05-12 06:17 -0700
      Re: Help on this typedef supercat@casperkitty.com - 2017-05-12 08:46 -0700
        Re: Help on this typedef joel.rees@gmail.com - 2017-05-12 18:11 -0700
          Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-12 18:37 -0700
            Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-13 09:44 -0700
              Re: Help on this typedef Keith Thompson <kst-u@mib.org> - 2017-05-13 13:47 -0700
                Re: Help on this typedef Robert Wessel <robertwessel2@yahoo.com> - 2017-05-14 00:28 -0500
                Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-14 13:39 -0700
                  Re: Help on this typedef raltbos@xs4all.nl (Richard Bos) - 2017-05-15 13:02 +0000
                    Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-15 07:30 -0700
          Re: Help on this typedef supercat@casperkitty.com - 2017-05-12 20:45 -0700
          Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-13 09:57 -0700
          Re: Help on this typedef Philip Lantz <prl@canterey.us> - 2017-05-13 12:07 -0700
          Re: Help on this typedef David Brown <david.brown@hesbynett.no> - 2017-05-14 15:34 +0200
        Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-14 12:48 -0700
          Re: Help on this typedef supercat@casperkitty.com - 2017-05-15 07:39 -0700
            Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-24 08:23 -0700
              Re: Help on this typedef supercat@casperkitty.com - 2017-05-24 09:17 -0700
                Re: Help on this typedef Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-27 06:15 -0700

Page 1 of 4  [1] 2 3 4  Next page →


#109727 — Help on this typedef

Fromfl <rxjwg98@gmail.com>
Date2017-05-10 19:12 -0700
SubjectHelp on this typedef
Message-ID<fc0d8572-2a06-4675-b83a-edb585ea1551@googlegroups.com>
Hi,

I see this typedef, which has '[1]' while the below declaration without it.
What use is '[1]'?

Thanks

-----------------
typedef __mpz_struct mpz_t[1];


//declaration:
  mpz_t    s_divisor;

[toc] | [next] | [standalone]


#109728

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2017-05-10 21:06 -0600
Message-ID<1bpofgqegz.fsf@pfeifferfamily.net>
In reply to#109727
fl <rxjwg98@gmail.com> writes:

> Hi,
>
> I see this typedef, which has '[1]' while the below declaration without it.
> What use is '[1]'?
>
> Thanks
>
> -----------------
> typedef __mpz_struct mpz_t[1];

This is saying that an mpz_t is an array of __mpz_struct's of length 1.
>
> //declaration:
>   mpz_t    s_divisor;

Because of the typedef, this is like saying

   __mpz_struct s_divisor[1];
   

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


#109729

FromKeith Thompson <kst-u@mib.org>
Date2017-05-10 20:11 -0700
Message-ID<lntw4s6q9v.fsf@kst-u.example.com>
In reply to#109727
fl <rxjwg98@gmail.com> writes:
> I see this typedef, which has '[1]' while the below declaration without it.
> What use is '[1]'?
>
> Thanks
>
> -----------------
> typedef __mpz_struct mpz_t[1];

It makes "mpz_t" an alias for the type "__mpz_struct[1]", an array of 1
__mpz_struct.

> //declaration:
>   mpz_t    s_divisor;

This defines an object named s_divisor of type mpz_t.
The declaration is equivalent to:

    __mpz_struct s_divisor[1];

An array of a single element of a given type is similar to single object
of that same type, but the type and the available operations are
different.

I suspect that this is used to achieve a kind of semi-fake
pass-by-reference semantics.  A function that takes an argument of type
mpz_t:

    void func(mpz_t param);

is exactly equivalent to:

    void func(__mpz_struct param[1]);

which in turn is exactly equivalent to:

    void func(__mpz_struct *param);

If you have questions about arrays and pointers, read section 6 of the
comp.lang.c FAQ, <http://www.c-faq.com/>.

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

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


#109735

FromDavid Brown <david.brown@hesbynett.no>
Date2017-05-11 10:03 +0200
Message-ID<of15n2$2og$1@dont-email.me>
In reply to#109729
On 11/05/17 05:11, Keith Thompson wrote:
> fl <rxjwg98@gmail.com> writes:
>> I see this typedef, which has '[1]' while the below declaration without it.
>> What use is '[1]'?
>>
>> Thanks
>>
>> -----------------
>> typedef __mpz_struct mpz_t[1];
> 
> It makes "mpz_t" an alias for the type "__mpz_struct[1]", an array of 1
> __mpz_struct.
> 
>> //declaration:
>>   mpz_t    s_divisor;
> 
> This defines an object named s_divisor of type mpz_t.
> The declaration is equivalent to:
> 
>     __mpz_struct s_divisor[1];
> 
> An array of a single element of a given type is similar to single object
> of that same type, but the type and the available operations are
> different.
> 
> I suspect that this is used to achieve a kind of semi-fake
> pass-by-reference semantics. 

An alternative possibility is that the array size in this code was not
always 1, or that the author thinks it might not always be 1 in the future.

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


#109754

Fromsupercat@casperkitty.com
Date2017-05-11 08:35 -0700
Message-ID<8ad1e08b-bdf9-4baa-a8b4-63bf48fb3e3d@googlegroups.com>
In reply to#109735
On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
> On 11/05/17 05:11, Keith Thompson wrote:
> > I suspect that this is used to achieve a kind of semi-fake
> > pass-by-reference semantics. 
> 
> An alternative possibility is that the array size in this code was not
> always 1, or that the author thinks it might not always be 1 in the future.

Using a literal 1 within a typedef in that case would seem unusual.  There
are some situations where the pseudo-pass-by-reference can be useful to
kludge around some of C's limitations.  While such usage isn't especially
common it's probably more common than any *other* use for size-1 array
typedefs.

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


#109809

FromDavid Brown <david.brown@hesbynett.no>
Date2017-05-12 10:34 +0200
Message-ID<of3rs7$ehf$2@dont-email.me>
In reply to#109754
On 11/05/17 17:35, supercat@casperkitty.com wrote:
> On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
>> On 11/05/17 05:11, Keith Thompson wrote:
>>> I suspect that this is used to achieve a kind of semi-fake
>>> pass-by-reference semantics. 
>>
>> An alternative possibility is that the array size in this code was not
>> always 1, or that the author thinks it might not always be 1 in the future.
> 
> Using a literal 1 within a typedef in that case would seem unusual.

It would be better to have:

#define noOfMPZs 1

and use that rather than "1" in the typedef.

But we don't know the origin of the code, or how well thought-out it is,
or what might have been put in as a quick hack.  We are just guessing.

>  There
> are some situations where the pseudo-pass-by-reference can be useful to
> kludge around some of C's limitations.  While such usage isn't especially
> common it's probably more common than any *other* use for size-1 array
> typedefs.
> 

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


#109827

Fromjoel.rees@gmail.com
Date2017-05-12 06:01 -0700
Message-ID<dbd22379-4b4f-45bd-9f5a-626a04e1efc4@googlegroups.com>
In reply to#109809
On Friday, May 12, 2017 at 5:34:30 PM UTC+9, David Brown wrote:
> On 11/05/17 17:35, supercat@somewhere wrote:
> > On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
> >> On 11/05/17 05:11, Keith Thompson wrote:
> >>> I suspect that this is used to achieve a kind of semi-fake
> >>> pass-by-reference semantics. 
> >>
> >> An alternative possibility is that the array size in this code was not
> >> always 1, or that the author thinks it might not always be 1 in the future.
> > 
> > Using a literal 1 within a typedef in that case would seem unusual.
>
> It would be better to have:
> 
> #define noOfMPZs 1
> 
> and use that rather than "1" in the typedef.

In this context "1" has deep meaning.

> But we don't know the origin of the code, or how well thought-out it is,
> or what might have been put in as a quick hack.  We are just guessing.

(sigh)

Let me help you:

    https://www.google.co.jp/search?q=__mpz_struct

--
Joel Rees

Twiddling my pi:
http://joels-programming-fun.blogspot.jp/2016/11/using-gmp-to-approximate-pi.html
https://ja.osdn.net/users/reiisi/pastebin/4462

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


#109849

FromKeith Thompson <kst-u@mib.org>
Date2017-05-12 09:38 -0700
Message-ID<lnvap658u2.fsf@kst-u.example.com>
In reply to#109809
David Brown <david.brown@hesbynett.no> writes:

> On 11/05/17 17:35, supercat@casperkitty.com wrote:
>> On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
>>> On 11/05/17 05:11, Keith Thompson wrote:
>>>> I suspect that this is used to achieve a kind of semi-fake
>>>> pass-by-reference semantics. 
>>>
>>> An alternative possibility is that the array size in this code was not
>>> always 1, or that the author thinks it might not always be 1 in the future.
>> 
>> Using a literal 1 within a typedef in that case would seem unusual.
>
> It would be better to have:
>
> #define noOfMPZs 1
>
> and use that rather than "1" in the typedef.
>
> But we don't know the origin of the code, or how well thought-out it is,
> or what might have been put in as a quick hack.  We are just guessing.

It's from GMP, the GNU multiple precision arithmetic library.

Quoting its documentation:

    When a GMP variable is used as a function parameter, it's
    effectively a call-by-reference, meaning if the function
    stores a value there it will change the original in the caller.
    Parameters which are input-only can be designated `const' to
    provoke a compiler error or warning on attempting to modify them.

    When a function is going to return a GMP result, it should
    designate a parameter that it sets, like the library functions
    do.  More than one value can be returned by having more than one
    output parameter, again like the library functions.  A `return'
    of an `mpz_t' etc doesn't return the object, only a pointer,
    and this is almost certainly not what's wanted.

(An alternative might have been to make mpz_t a small struct, and
require explicit pointers to simulate pass-by-reference.)

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

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


#109826

Fromjoel.rees@gmail.com
Date2017-05-12 05:08 -0700
Message-ID<faaaf47a-51ec-4323-aba2-18cabef07fe8@googlegroups.com>
In reply to#109754
On Friday, May 12, 2017 at 12:35:45 AM UTC+9, supe...@casperkitty.com wrote:
> On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
> > On 11/05/17 05:11, Keith Thompson wrote:
> > > I suspect that this is used to achieve a kind of semi-fake
> > > pass-by-reference semantics. 
> > 
> > An alternative possibility is that the array size in this code was not
> > always 1, or that the author thinks it might not always be 1 in the future.
> 
> Using a literal 1 within a typedef in that case would seem unusual.  There
> are some situations where the pseudo-pass-by-reference can be useful to
> kludge around some of C's limitations.  While such usage isn't especially
> common it's probably more common than any *other* use for size-1 array
> typedefs.

An indefinite array type has more limitations than a type of an array with one element.

Both, of course, can refer to an array of more than one element when instantiated.

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


#109912

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-13 14:25 -0700
Message-ID<kfnd1bcsb3d.fsf@x-alumni2.alumni.caltech.edu>
In reply to#109826
joel.rees@gmail.com writes:

> On Friday, May 12, 2017 at 12:35:45 AM UTC+9, supe...@casperkitty.com wrote:
>> On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
>>> On 11/05/17 05:11, Keith Thompson wrote:
>>>> I suspect that this is used to achieve a kind of semi-fake
>>>> pass-by-reference semantics.
>>>
>>> An alternative possibility is that the array size in this code was not
>>> always 1, or that the author thinks it might not always be 1 in the future.
>>
>> Using a literal 1 within a typedef in that case would seem unusual.  There
>> are some situations where the pseudo-pass-by-reference can be useful to
>> kludge around some of C's limitations.  While such usage isn't especially
>> common it's probably more common than any *other* use for size-1 array
>> typedefs.
>
> An indefinite array type has more limitations than a type of an
> array with one element.

In some ways it has more, in other ways it has fewer.

> Both, of course, can refer to an array of more than one element
> when instantiated.

What do you mean?  AFAIK there is no way to "instantiate" an
indefinite array type.

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


#110002

Fromjoel.rees@gmail.com
Date2017-05-14 23:36 -0700
Message-ID<7828b0dd-de46-40a2-9636-81117d1f17f6@googlegroups.com>
In reply to#109912
On Sunday, May 14, 2017 at 6:25:48 AM UTC+9, Tim Rentsch wrote:
> joel.rees@gmail.com writes:
> 
> > On Friday, May 12, 2017 at 12:35:45 AM UTC+9, supe...@casperkitty.com wrote:
> >> On Thursday, May 11, 2017 at 3:04:00 AM UTC-5, David Brown wrote:
> >>> On 11/05/17 05:11, Keith Thompson wrote:
> >>>> I suspect that this is used to achieve a kind of semi-fake
> >>>> pass-by-reference semantics.
> >>>
> >>> An alternative possibility is that the array size in this code was not
> >>> always 1, or that the author thinks it might not always be 1 in the future.
> >>
> >> Using a literal 1 within a typedef in that case would seem unusual.  There
> >> are some situations where the pseudo-pass-by-reference can be useful to
> >> kludge around some of C's limitations.  While such usage isn't especially
> >> common it's probably more common than any *other* use for size-1 array
> >> typedefs.
> >
> > An indefinite array type has more limitations than a type of an
> > array with one element.
> 
> In some ways it has more, in other ways it has fewer.
> 
> > Both, of course, can refer to an array of more than one element
> > when instantiated.
> 
> What do you mean?  AFAIK there is no way to "instantiate" an
> indefinite array type.

Bad phrasing, I guess. "... when in use." probably would have been 
more accurate. 

--
Joel Rees

Randomly ranting:
http://reiisi.blogspot.com

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


#110034

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-15 07:23 -0700
Message-ID<kfninl2nqqy.fsf@x-alumni2.alumni.caltech.edu>
In reply to#110002
joel.rees@gmail.com writes:

> On Sunday, May 14, 2017 at 6:25:48 AM UTC+9, Tim Rentsch wrote:
>> joel.rees@gmail.com writes:
[...]
>>> An indefinite array type has more limitations than a type of an
>>> array with one element.
>>
>> In some ways it has more, in other ways it has fewer.
>>
>>> Both, of course, can refer to an array of more than one element
>>> when instantiated.
>>
>> What do you mean?  AFAIK there is no way to "instantiate" an
>> indefinite array type.
>
> Bad phrasing, I guess.  "... when in use." probably would have been
> more accurate.

Ah.  In that case I must demur regarding part of your later
statement.  An access through an array type of extent 1 is
not definedly allowed to access elements after the element
at index 0.

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


#110286

Fromjoel.rees@gmail.com
Date2017-05-18 07:40 -0700
Message-ID<799899ab-ccf3-49a4-a928-d405dc142fff@googlegroups.com>
In reply to#110034
On Monday, May 15, 2017 at 11:23:23 PM UTC+9, Tim Rentsch wrote:
> joel.rees@somewhere writes:
> 
> > On Sunday, May 14, 2017 at 6:25:48 AM UTC+9, Tim Rentsch wrote:
> >> joel.rees@somewhere writes:
> [...]
> >>> An indefinite array type has more limitations than a type of an
> >>> array with one element.
> >>
> >> In some ways it has more, in other ways it has fewer.
> >>
> >>> Both, of course, can refer to an array of more than one element
> >>> when instantiated.
> >>
> >> What do you mean?  AFAIK there is no way to "instantiate" an
> >> indefinite array type.
> >
> > Bad phrasing, I guess.  "... when in use." probably would have been
> > more accurate.
> 
> Ah.  In that case I must demur regarding part of your later
> statement.  An access through an array type of extent 1 is
> not definedly allowed to access elements after the element
> at index 0.

typedef string_header_s struct
{  short length; /* limited length */
   char text[ 1 ];
} string_header_t;

And before you C++ types came around, we just left the array size 
out: char text[]. But that was declared in all cases to be equivalent
to char *, so it means something else, now. And if that's what you 
mean in such a header, you say char *, instead.

Now, to forestall your initial complaints, I'll point out that this 
header is not intended to be directly allocated with malloc() and 
sizeof like most structures are allocated:

#if defined DO_IT_WRONG
    malloc( sizeof (string_header_t) ) Don't do this!
#endif

One could allocate it like this:

string_header_t string_alloc( size_t length )
{  return malloc( length + sizeof (string_header_t) );
}

particularly if you mean length to include the trailing NUL.

Usually, though, you use this kind of header with your own 
allocation. You usually set up your own string pool and manage 
it yourself:
-------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct string_header_s
{  short length;
   char string[ 1 ];
} string_header_t;

char bigblock[ 100000 ];
char * here = bigblock;

string_header_t * string_allocate( long length )
{  char * place = here;;
   if ( ( place = here + length + sizeof (string_header_t) ) >= bigblock + 100000 )
   {  return NULL;
   }
   here = place;
   ( (string_header_t *) place )->length = length;
   return (string_header_t *) place;
}

string_header_t * string_save( char string[] )
{  long length = strlen( string );
   string_header_t * headerp = string_allocate( length );
   memcpy( headerp->string, string, length );
   headerp->string[ length ] = '\0';
   return headerp;
}

void print_string( string_header_t * header )
{  int i;
   for ( i = 0; i < header->length; ++i )
   {  putchar( header->string[ i ] );
   }
}


int main ( int argc, char * argv[] )
{  string_header_t * thing;

   thing = string_save( "hello" );

   /* ... */

   print_string( thing );
   putchar( '\n' );

   return EXIT_SUCCESS;
}
----------------------

--
Joel Rees

Delusions of being a novelist:
http://reiisi.blogspot.com/p/novels-i-am-writing.html

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


#110312

FromKeith Thompson <kst-u@mib.org>
Date2017-05-18 09:35 -0700
Message-ID<lnwp9e15td.fsf@kst-u.example.com>
In reply to#110286
joel.rees@gmail.com writes:
> On Monday, May 15, 2017 at 11:23:23 PM UTC+9, Tim Rentsch wrote:
[...]
>> Ah.  In that case I must demur regarding part of your later
>> statement.  An access through an array type of extent 1 is
>> not definedly allowed to access elements after the element
>> at index 0.
>
> typedef string_header_s struct
> {  short length; /* limited length */
>    char text[ 1 ];
> } string_header_t;

That's called the "struct hack", and it was always of questionable
validity.  You can likely get away with allocating extra memory and
referring to, for example, obj.text[10], but the behavior is undefined.

C99 introduced flexible array members, described in N1570 6.7.2.1p18,
as a well-defined replacement for the struct hack.  See also question
2.6 of the comp.lang.c FAQ, <http://c-faq.com/>.

> And before you C++ types came around, we just left the array size 
> out: char text[]. But that was declared in all cases to be equivalent
> to char *, so it means something else, now. And if that's what you 
> mean in such a header, you say char *, instead.

Prior to C99's instroduction of flexible array members, defining a
struct member as `char text[]` was invalid.

And no, `char text[]` is in no way equivalent to `char *text`.  See
section 6 of the comp.lang.c FAQ.

You can define a pointer member, but then you have to allocate memory
for it to point to.  With an array member, the memory is allocated
within the struct object itself.

[...]

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

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


#110318

Fromsupercat@casperkitty.com
Date2017-05-18 10:59 -0700
Message-ID<aacc15a1-bc91-46bd-9a8d-6ce087cf20e6@googlegroups.com>
In reply to#110312
On Thursday, May 18, 2017 at 11:35:33 AM UTC-5, Keith Thompson wrote:
> That's called the "struct hack", and it was always of questionable
> validity.  You can likely get away with allocating extra memory and
> referring to, for example, obj.text[10], but the behavior is undefined.

The Standard never defined the behavior, but implementers back then
recognized that features which were useful should be supported on all
platforms where they were practical, without regard for whether the
Standard mandated such support.  The construct was widespread well before
C89 was published (though a lot of code used a superior version where the
array size was given as zero until the standard outlawed that) and I
would regard as ludicrous the idea that the failure of the Standards
Committee to recognize it should have caused compilers to withdraw support.

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


#110356

Fromjoel.rees@gmail.com
Date2017-05-18 23:40 -0700
Message-ID<1c41ec70-5868-4a28-a724-58f4bb70e593@googlegroups.com>
In reply to#110312
On Friday, May 19, 2017 at 1:35:33 AM UTC+9, Keith Thompson wrote:
> joel.rees@somewhere writes:
> > On Monday, May 15, 2017 at 11:23:23 PM UTC+9, Tim Rentsch wrote:
> [...]
> >> Ah.  In that case I must demur regarding part of your later
> >> statement.  An access through an array type of extent 1 is
> >> not definedly allowed to access elements after the element
> >> at index 0.
> >
> > typedef string_header_s struct
> > {  short length; /* limited length */
> >    char text[ 1 ];
> > } string_header_t;
> 
> That's called the "struct hack", and it was always of questionable
> validity.  You can likely get away with allocating extra memory and
> referring to, for example, obj.text[10], but the behavior is undefined.

You don't believe in reading before you spout, I take it.

Go back, read the source you clipped and tell me that again.

If you prove that you have read and understood the source that you 
say is undefined, I'll listen to you.

Otherwise, <shrug>.

> [...]
> 
> -- 
> 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"

--
Joel Rees

Randomly ranting:
http://reiisi.blogspot.com

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


#110379

Fromjadill33@gmail.com
Date2017-05-19 08:12 -0700
Message-ID<23afe8df-f24e-4419-bfd0-091b96fb575f@googlegroups.com>
In reply to#110356
On Friday, May 19, 2017 at 2:41:05 AM UTC-4, joel...@gmail.com wrote:
> On Friday, May 19, 2017 at 1:35:33 AM UTC+9, Keith Thompson wrote:
> > joel...@somewhere writes:
> > > On Monday, May 15, 2017 at 11:23:23 PM UTC+9, Tim Rentsch wrote:
> > [...]
> > >> Ah.  In that case I must demur regarding part of your later
> > >> statement.  An access through an array type of extent 1 is
> > >> not definedly allowed to access elements after the element
> > >> at index 0.
> > >
> > > typedef string_header_s struct
> > > {  short length; /* limited length */
> > >    char text[ 1 ];
> > > } string_header_t;
> > 
> > That's called the "struct hack", and it was always of questionable
> > validity.  You can likely get away with allocating extra memory and
> > referring to, for example, obj.text[10], but the behavior is undefined.
> 
> You don't believe in reading before you spout, I take it.
> 
> Go back, read the source you clipped and tell me that again.
> 
> If you prove that you have read and understood the source that you 
> say is undefined, I'll listen to you.
> 
> Otherwise, <shrug>.

<snip>

If you want to have some kind of fat pointer, like a string referenced with
a char* with a built-in size, you can still do that, but the key is to make
sure the alignment for the pointer to your string is valid for the maximum
alignment for your implementation.

In C11, this is defined in max_align_t, but in versions before, you'd have
to sizeof an ugly union that covers the unique range of basic types.  It's
basically what malloc does to guarantee that any allocation is properly
aligned for any given type.

So, the key is to create a blob that's of size max_align_t or equivalent
sizeof union type (or a multiple of maxalign_t if there's a lot of fat),
and add that to the allocation of the object you wish to allocate (in
this case a string).  Then in your allocation, you allocate the total
chunk of memory, but return a pointer at an offset that points to your
object.  You would return a pointer at the memory address location
referenced by '*'.

^       -> *
|   size   |                string                 |
0          8 (or 16)

If it's a string that has a length field, and max_align_t is 8 bytes, then
you would have to add 8 bytes to every allocation to guarantee alignment
for any generalized type.  The nice thing is that you can still pass your
fat pointer string object to standard library functions and it'll still
work.  You just need to be careful when freeing that you go back 8 bytes
to free the actual address that malloc gave you or you'll corrupt the
allocator.  You'd have to be very careful with functions like strdup as
you'll end up mixing fat and regular pointers.

To store your length, you'd cast the address referenced by '^' to your type
of choice and set the value, e.g. *((size_t*)p) = strlen (string).

Using this technique, you can do some pretty cool stuff, like introduce
an allocator to artificially run out of memory at a given threshold, or if
you're storing the sizes of heap allocations, keep statistics of your
memory usage, (i.e. if the size of the object is attached to the pointer,
you know how much is released when you free).  The caveat is that the
compiler gives you no notice if you happen to use the wrong pointer at
the wrong time, so you can have normal looking code that's really messed
up, i.e. don't free '*', free '^', make sure you set the size at '^'.

^       -> *
|   size   |                string                 |
0          8

If you package it up in proper 'alloc' and 'free' functions, it's
*relatively* safe to use.  It's fairly easy to get bitten though and
introduce very hard to find errors (imo pointer corruption is probably
the worst kind of problem to track down).

\code
size_t current_memory = 0;

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

  /*
   * To track the amount of used memory, each memory allocation is
   * prefixed with a size_t object that allows the free function to
   * update 'current_memory' correctly when releasing memory.
   */
  mem = malloc( c_maxalign_sizeof (size_t) + size );

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

    current_memory += size;
  }

  return p;
}

void track_free( void* p )
{
  void* mem = NULL;
  size_t p_size;

  if ( p )
  {
    mem = (unsigned char*)p - c_maxalign_sizeof (size_t);
    p_size = *((size_t*)mem);

    free( mem );

    current_memory -= p_size;
  }
}
\endcode

You'll get varying opinions about how kosher this type of pointer hacking
is, but it is useful in certain contexts.

Best regards,
John D.

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


#110381

Fromsupercat@casperkitty.com
Date2017-05-19 08:41 -0700
Message-ID<fc73e3ed-02bd-4069-8f11-662bdf4cf37d@googlegroups.com>
In reply to#110379
On Friday, May 19, 2017 at 10:13:07 AM UTC-5, jadi... wrote:
> If you want to have some kind of fat pointer, like a string referenced with
> a char* with a built-in size, you can still do that, but the key is to make
> sure the alignment for the pointer to your string is valid for the maximum
> alignment for your implementation.

That's the approach used by the BSTR type in Windows.  Note that alignment
won't be an issue if either:

  -1- The processor can handle unaligned reads (as with processors running
      Windows), or

  -2- Code that reads the length assembles it out of bytes

Except for really short strings, the time required to assemble the length
from multiple byte reads would be much longer than the time required to
use a single word read, but less than the time required to check each byte
of a string against zero.

If portability to machines that don't accommodate unaligned reads were an
issue, I'd favor a variable-size encoding for the length (since short
strings are more common than long strings, a byte read and bit test may
be faster than four byte reads and three shifts) but if code will only be
run on platforms that support unaligned reads, the performance advantages
of being able to use a single 32-bit load may be sufficient to justify the
waste of space on short strings.

A more interesting question is whether it's better to have a string pointer
identify the character storage directly, or allow for the possibility that
it might either target a string or a descriptor object.  Allowing for the
latter would add a little overhead to code which processes strings, but
make it possible for a pointer to encapsulate a reference to either an
entire string object or an arbitrary substring thereof.

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


#110386

Fromjadill33@gmail.com
Date2017-05-19 09:41 -0700
Message-ID<5c12f3a1-e8b6-4dbf-bf15-74f555c8e470@googlegroups.com>
In reply to#110381
On Friday, May 19, 2017 at 11:41:42 AM UTC-4, supe...@casperkitty.com wrote:
> On Friday, May 19, 2017 at 10:13:07 AM UTC-5, jadi... wrote:
> > If you want to have some kind of fat pointer, like a string referenced with
> > a char* with a built-in size, you can still do that, but the key is to make
> > sure the alignment for the pointer to your string is valid for the maximum
> > alignment for your implementation.
> 
> That's the approach used by the BSTR type in Windows.  Note that alignment
> won't be an issue if either:
> 
>   -1- The processor can handle unaligned reads (as with processors running
>       Windows), or
> 
>   -2- Code that reads the length assembles it out of bytes
> 
> Except for really short strings, the time required to assemble the length
> from multiple byte reads would be much longer than the time required to
> use a single word read, but less than the time required to check each byte
> of a string against zero.
> 
> If portability to machines that don't accommodate unaligned reads were an
> issue, I'd favor a variable-size encoding for the length (since short
> strings are more common than long strings, a byte read and bit test may
> be faster than four byte reads and three shifts) but if code will only be
> run on platforms that support unaligned reads, the performance advantages
> of being able to use a single 32-bit load may be sufficient to justify the
> waste of space on short strings.
> 
> A more interesting question is whether it's better to have a string pointer
> identify the character storage directly, or allow for the possibility that
> it might either target a string or a descriptor object.  Allowing for the
> latter would add a little overhead to code which processes strings, but
> make it possible for a pointer to encapsulate a reference to either an
> entire string object or an arbitrary substring thereof.

The big problem with micro optimization to me is that it's really hard to
get the packaging right to a point where you increase the performance without
dramatically increasing the cost of reduced maintain-ability of the source
code.  The danger is spending a lot of effort on writing fragile code that
no one wants to maintain even if it's "fast".

Best regards,
John D.

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


#110384

FromKeith Thompson <kst-u@mib.org>
Date2017-05-19 09:34 -0700
Message-ID<lno9uo24cj.fsf@kst-u.example.com>
In reply to#110356
joel.rees@gmail.com writes:
> On Friday, May 19, 2017 at 1:35:33 AM UTC+9, Keith Thompson wrote:
>> joel.rees@somewhere writes:
>> > On Monday, May 15, 2017 at 11:23:23 PM UTC+9, Tim Rentsch wrote:
>> [...]
>> >> Ah.  In that case I must demur regarding part of your later
>> >> statement.  An access through an array type of extent 1 is
>> >> not definedly allowed to access elements after the element
>> >> at index 0.
>> >
>> > typedef string_header_s struct
>> > {  short length; /* limited length */
>> >    char text[ 1 ];
>> > } string_header_t;
>> 
>> That's called the "struct hack", and it was always of questionable
>> validity.  You can likely get away with allocating extra memory and
>> referring to, for example, obj.text[10], but the behavior is undefined.
>
> You don't believe in reading before you spout, I take it.

I do believe in it, though I don't always succeed.  I have occasionally
made the mistake of posting without reading and understanding an entire
article, and when I do that I appreciate having it pointed out.

> Go back, read the source you clipped and tell me that again.

Ok, I've re-read your previous article and I'll tell you that again.
The behavior is undefined.

Here's a demo program, based on your declaration above with the syntax
error corrected:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
    typedef struct string_header_s {
        short length; /* limited length */
        char text[ 1 ];
    } string_header_t;

    string_header_t *p = malloc(sizeof *p + 10); /* more than we need */
    if (p == NULL) exit(EXIT_FAILURE);
    p->length = 4;
    strcpy(p->text, "abcd");
    printf("p->text[3] = '%c'\n", p->text[3]);
}

When I compile and run this on my system, I get no compile-time
diagnostics and the output, as expected, is:

p->text[3] = 'd'

But both the strcpy() call and the reference to p->text[3] have
undefined behavior.  Concentrating on the latter, the indexing
operator [] is defined in terms of pointer addition, in this case
(p->text + 3).  The description of pointer addition, in N1570
6.5.6p8, says:

    If both the pointer operand and the result point to elements
    of the same array object, or one past the last element of the
    array object, the evaluation shall not produce an overflow;
    otherwise, the behavior is undefined.

The array object in question is p->text, which is of type char[1].
We've used malloc to allocate additional memory past the end of
that array object, but it's not part of the array object.

Most, perhaps all, C compilers will accept this and generate code
that behaves as expected, precisely because the struct hack is
a common idiom.  Nevertheless, the behavior is not defined by
the standard.

If you disagree, I'm paying attention.

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

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


Page 1 of 4  [1] 2 3 4  Next page →

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


csiph-web