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


#110483

Fromsupercat@casperkitty.com
Date2017-05-22 10:50 -0700
Message-ID<ec43ebc2-e710-47f3-959a-d35554dee3c3@googlegroups.com>
In reply to#110452
On Saturday, May 20, 2017 at 9:47:02 AM UTC-5, james...@verizon.net wrote:
> I should answer it directly. First of all, your list of the various
> possibilities did not include the one possibility that actually applied.

I'd say #2 would seem to match the case you describe; if the Standard
were adequately clear on a subject, it should be possible to answer
any questions about its meaning merely by citing and quoting the relevant
portions; if a question that would need to be answered, cannot be answered
merely by quoting the Standard, I would regard that as indicative of a
defect which should be corrected by, at minimum, adding a footnote to
future standards that would clarify the issue.

Also, who writes the answers to DRs?  Are they voted upon by the Committee as
a whole?  There are certain places where the Standard appears to deliberately
avoid clarifying examples that are so obviously essential that the only
plausible explanations are either that the Committee was being absurdly dumb
or else no consensus could be reached as to whether they should be defined
or not.  For example, under 6.5.2.3, there should be an example where structs
containing a Common Initial Sequence are accessed via pointers of their
respective types, at places where a complete union definition containing
both structures is visible.  I personally think the language is quite clear
as saying such behavior is defined (saying CIS members may be inspected
"anywhere that a declaration of the complete type of the union is visible"
would be redundant if such inspection had to be done through lvalues of
union type, since such accesses can't possibly be made anywhere else) but
compiler writers don't follow that.

> Secondly, committee resolutions never take the form of advice for implementors
> about how to deal with the issue raised by the DR - they either express what the
> committee believes is the correct interpretation of the words as they are
> currently written (in which cases implementors who wish to conform to the
> standard should modify their implementation, if necessary, to match that
> interpretation), or they recommend that the words be changed (in which case
> implementors have the option of anticipating the correction by implementing it
> as an extension now, or waiting until the correction has been approved before
> implementing it as a conformance requirement).

There are a number places where it would make sense for 99.9% of
implementations to behave the same way, and to allow programmers to
exploit that if they don't need to support the unusual 0.1%.  The
Standard leaves such behaviors Undefined so as to avoid forbidding
implementations from doing some other sensible behavior, sometimes
even when an earlier standard defined the behavior (e.g. -1<<1).

What's really needed, but what the Standard has avoided for some (likely
political) reasons, would be an effort to recognize behaviors that are
commonplace but not universal.  Ironically, I suspect it's politically
easier to recognize a behavior that's supported by 50% of implementations
than one that's supported by 99%, since the latter would be seen as
marginalizing the 1%.

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


#110313

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-05-18 12:37 -0400
Message-ID<8351ad3e-a9af-2bcf-f640-8f9ba8529aca@verizon.net>
In reply to#110286
On 05/18/2017 10:40 AM, joel.rees@gmail.com wrote:
> 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[].

I don't know what connection you think this has to C++, but I suspect 
you're mistaken. Unlike C, C++ has never given well-defined behavior to 
any version of this approach.

Using [1] is the original "struct hack", and as Tim pointed out, any 
attempt to access text[i] for i>0 had undefined behavior. It probably 
works on just about any C90 compiler, but that's merely a historical 
fact, it's not something the C standard ever guaranteed.

Using [0] for the length is a constraint violation, but allowing it to 
be used for this purpose was a common extension to C. The 
implementations that provided this extension defined it's behavior, but 
the C standard itself never did so.

Using [] for this purpose is a feature that was added in C99; an array 
declared in that fashion as the last member of a struct is called a 
flexible array member. And it's only the use of flexible array members 
for this purpose that has defined behavior.


> ... But that was declared in all cases to be equivalent
> to char *, so it means something else, now. ...

Who declared that? No version of the C standard does so.

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


#110324

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-05-18 20:02 +0100
Message-ID<87fug2yond.fsf@bsb.me.uk>
In reply to#110286
joel.rees@gmail.com writes:

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

No, the old idiom as an array length 1 as above.  The form sanctioned by
the newer C standards (C99 and up) is to leave the size out, provided
this is the last member of a struct.  (I don't know what C++ has to do
with it -- I took "you C++ types" to refer to people, but I don't know
who.)

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

No.  char x[] and char *x mean the same thing in a parameter declaration
but not elsewhere, and definitely not in a struct!

<snip>
> 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 )

This test is, technically, wrong.  Most people would not worry about it,
but once you know what C guarantees and what it does not guarantee it's
hard to go back[1].  I'd just keep a counter of the bytes used to avoid
a potentially undefined pointer construction and test.

>    {  return NULL;
>    }
>    here = place;
>    ( (string_header_t *) place )->length = length;
>    return (string_header_t *) place;
> }

You also have potential alignment problems.

<snip>

[1] You can only generate pointers that point into, or just past, an
array, and pointer can only be compared with <, <=, > and >= if they
point into the same object (or just past).

-- 
Ben.

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


#110360

Fromjoel.rees@gmail.com
Date2017-05-19 00:20 -0700
Message-ID<431ea3d0-2d91-40b9-8988-868be7f0382e@googlegroups.com>
In reply to#110324
On Friday, May 19, 2017 at 4:02:24 AM UTC+9, Ben Bacarisse wrote:
> joel.rees@somewhere writes:
> 
> > 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[].
> 
> No, the old idiom as an array length 1 as above.  The form sanctioned by
> the newer C standards (C99 and up) is to leave the size out, provided
> this is the last member of a struct.  (I don't know what C++ has to do
> with it -- I took "you C++ types" to refer to people, but I don't know
> who.)

:|

> > 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.
> 
> No.  char x[] and char *x mean the same thing in a parameter declaration
> but not elsewhere, and definitely not in a struct!

Yeah, parameters. You could increment a parameter declared that way as 
if it were a pointer, but you couldn't assign a struct member delared 
empty. I keep forgetting.

I have this vague memory that the reasoning behind the array size 1 hack 
was to avoid conflation with the tendency to assume a size left out was
a pointer.

> <snip>
> > 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 )
> 
> This test is, technically, wrong. 

Erk. Forgetting that pointers in non-linear address spaces can wrap weird.

Okay, ignoring the potential alignment problems you point out below, 

    if ( ( bigblock + 100000 - here - length - sizeof (string_header_t) ) <= 0 )

and that won't help me if here somehow ends up pointing outside the array.

> Most people would not worry about it,
> but once you know what C guarantees and what it does not guarantee it's
> hard to go back[1]. 

I'm proof that ain't true, I guess. :-/

I've sometimes been of a mind that address involving truncated segment 
registers should have been treated as something other than pointers.

> I'd just keep a counter of the bytes used to avoid
> a potentially undefined pointer construction and test.

I have this love-hate relationship with counters. I'm not sure why.

Might be the one-offs.

> >    {  return NULL;
> >    }
> >    here = place;
> >    ( (string_header_t *) place )->length = length;
> >    return (string_header_t *) place;
> > }
> 
> You also have potential alignment problems.

<8-o

> <snip>
> 
> [1] You can only generate pointers that point into, or just past, an
> array, and pointer can only be compared with <, <=, > and >= if they
> point into the same object (or just past).
> 
> -- 
> Ben.

Thanks for looking at the code.

And I guess I should acknowledge that Keith and others were trying to
point out that the standard had flip-flopped on which hack to use for 
indeterminant, that is, flexible, arrays while I was busy working with 
other languages in the previous decade.

--
Joel Rees

Randing rantomly:
http://reiisi.blogspot.com

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


#110388

FromKeith Thompson <kst-u@mib.org>
Date2017-05-19 09:51 -0700
Message-ID<lnk25c23it.fsf@kst-u.example.com>
In reply to#110360
joel.rees@gmail.com writes:
> On Friday, May 19, 2017 at 4:02:24 AM UTC+9, Ben Bacarisse wrote:
[...]
>> No.  char x[] and char *x mean the same thing in a parameter declaration
>> but not elsewhere, and definitely not in a struct!
>
> Yeah, parameters. You could increment a parameter declared that way as 
> if it were a pointer, but you couldn't assign a struct member delared 
> empty. I keep forgetting.

A parameter declared that way *is* a pointer.  For example, this:
    void func(int param[42]);
really means this:
    void func(int *param);
`param` simply is not an array.  (And the 42 is quietly ignored,
which is unfortunate.)

> I have this vague memory that the reasoning behind the array size 1 hack 
> was to avoid conflation with the tendency to assume a size left out was
> a pointer.

There was a time, very early in the design of C, when [] was used
to declare pointers, and defining an array object would create an
implicit pointer object pointing to the array's initial element.
Dennis Ritchie changed that because it didn't work when structures
have members that are arrays.  For example, if you have a structure
like this:

    struct foo {
        int arr[10];
    };

and the definition of arr creates a pointer, then copying the structure
would copy the pointer, and the copy would point back to the original
object.

This change was made some time around the transition from "NB"
to C.  See <https://www.bell-labs.com/usr/dmr/www/>, and search for
"Embryonic C".

Unfortunately, the myth that C arrays are really just pointers has
survived long past the time when there was any truth to it.

Suggested reading: Section 6 of the comp.lang.c FAQ,
<http://www.c-faq.com/>.  (And then the rest of it.)

[...]

> And I guess I should acknowledge that Keith and others were trying to
> point out that the standard had flip-flopped on which hack to use for 
> indeterminant, that is, flexible, arrays while I was busy working with 
> other languages in the previous decade.

I wouldn't say the standard flip-flopped.  The C89/C90 standard doesn't
mention the struct hack.  C programmers invented it, and it happened to
work.  C99 introduced flexible array members as a standard-endorsed way
to achieve the same effect while avoiding undefined behavior.

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


#110396

Fromsupercat@casperkitty.com
Date2017-05-19 10:31 -0700
Message-ID<373c721b-997a-4688-b048-b45e9b8e463c@googlegroups.com>
In reply to#110388
On Friday, May 19, 2017 at 11:52:07 AM UTC-5, Keith Thompson wrote:

> > And I guess I should acknowledge that Keith and others were trying to
> > point out that the standard had flip-flopped on which hack to use for 
> > indeterminant, that is, flexible, arrays while I was busy working with 
> > other languages in the previous decade.
> 
> I wouldn't say the standard flip-flopped.  The C89/C90 standard doesn't
> mention the struct hack.  C programmers invented it, and it happened to
> work.  C99 introduced flexible array members as a standard-endorsed way
> to achieve the same effect while avoiding undefined behavior.

The struct hack was in use long before C89 was published, and if there
are two ways of reading the Standard--one of which irreparable break such
code and semantically devastate the language, and one of which would be
compatible with it, common sense would suggest that the authors of the
Standard would have the latter (unless they were lying about wanting to
avoid breaking existing code).

It would have been entirely reasonable for C99 to officially deprecate the
struct hack, since it offered a practical and mostly-superior alternative,
but it is not reasonable to describe such a feature as offering major new
semantics beyond what had been added 25 years before when C acquired the
ability to nest array types in structures.  The only way FAM could be seen
as offering major new semantics would be by interpreting C89 as a major step
back relative to the various forms of the language that had been produced
in the preceding 15 years.

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


#110412

FromIke Naar <ike@iceland.freeshell.org>
Date2017-05-19 19:48 +0000
Message-ID<slrn3vfsohuj6a.7hu.ike@iceland.freeshell.org>
In reply to#110286
On 2017-05-18, joel.rees@gmail.com <joel.rees@gmail.com> wrote:
> #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 )

It's undefined behaviour to produce a pointer beyond one-past-the-end of an array.
So 'here + length + sizeof(string_header_t)' has undefined behaviour if
(here - bigblock) + length + sizeof (string_header_t) > sizeof bigblock' .

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


#110456

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-20 08:47 -0700
Message-ID<kfn8tlrjzsu.fsf@x-alumni2.alumni.caltech.edu>
In reply to#110286
joel.rees@gmail.com writes:

> 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:
>>
>> [...pre-C99 flexible array members...]
>>
>> 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.

I see you have walked back some comments about the behavior of
indexing, so I won't revisit that, but I wanted to respond on
some other code items.  (Some code below reformatted for line
length.)

> typedef string_header_s struct
> {  short length; /* limited length */
>    char text[ 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;
> }

I thought it might be helpful to show how this function could be
written to avoid some of the problems it has (which I think you
mostly know about already).  Please excuse changes in using white
space.  (Disclaimer: not compiled.)

    string_header_t *
    string_allocate( long length ){
        string_header_t *it = (void*) here;
        long it_size        = sizeof *it;
        long needed         = 1 +  (it_size + length - 1) /it_size *it_size;
        char *block_limit   = bigblock + sizeof bigblock;

        if(  block_limit - here < needed  )  return  NULL;

        here += needed;
        return  it->length = length,  it;
    }

The initializer for 'needed' shows how to make sure the amount
allocated is a suitable multiple of the struct size, ie, by
rounding up.

The if() test shows how to check if enough space is available
without running into problems of "pointer overflow".


> 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;
> }

And also for this routine, because it needs to protect against
allocation failure (also not compiled):

    string_header_t *
    string_save( char string[] ){
       long n = strlen( string );
       string_header_t *it = string_allocate( n );
       return  it  ?  memcpy( it->string, string, n+1 ),  it  :  NULL;
    }

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


#110794

From"Patrick.Schluter" <Patrick.Schluter@free.fr>
Date2017-05-27 18:50 +0200
Message-ID<5929ae51$0$10177$426a74cc@news.free.fr>
In reply to#109754
Le 11.05.2017 à 17:35, supercat@casperkitty.com a écrit :
> 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.
> 
The va_arg on Linux x86_64 is implemented that way. An array of 1 
element struct containing the different pointers and number of values.

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


#109828

Fromjoel.rees@gmail.com
Date2017-05-12 06:17 -0700
Message-ID<d5cc0ecd-9494-4bd2-a8b3-505a00faf06d@googlegroups.com>
In reply to#109727
On Thursday, May 11, 2017 at 11:12:55 AM UTC+9, fl wrote:
> 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;

I was thinking I had some sample source using GMP's arbitrary precision 
integers, but it's arbitrary precision floating point.

Just in case it's useful for the usage patterns:

https://ja.osdn.net/users/reiisi/pastebin/4462

And the explanation:

http://joels-programming-fun.blogspot.jp/2016/11/using-gmp-to-approximate-pi.html

(Serious boondoggle code.)

Anyway, an array of one is most commonly a signal that you are 
allocating and using variable length arrays.

--
Joel Rees

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

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


#109842

Fromsupercat@casperkitty.com
Date2017-05-12 08:46 -0700
Message-ID<7f9425fb-583a-4571-820e-bca3025172ec@googlegroups.com>
In reply to#109828
On Friday, May 12, 2017 at 8:17:46 AM UTC-5, joel...@gmail.com wrote:
> Anyway, an array of one is most commonly a signal that you are 
> allocating and using variable length arrays.

IMHO, the struct hack would have been cleaner in many ways had the authors
of the Standard not opted to disallow arrays of size zero.  The only good
reason I can see for disallowing such arrays would have been to ensure the
correct "behavior" of a existing code that uses constructs like

    struct dummyName { int x[sizeof foo == 50]; };

as a form of compile-time assertion.  I recognize that requiring compilers
to accept arrays of size zero [before the Standard, some did and some did
not] could have silently undermined what could be important compile-time
safety checks, but given that compilers would be allowed to warn about
zero-size arrays even if the Stanard allowed them, and could have offered
a non-conforming mode that would break the build on such declarations, I
would not think that would have been a major issue.

Otherwise, I think it would have been useful to allow zero-size objects
with the privisos that:

(1) the address of a stand-alone zero-size object may or may not match the
address of any other, at the compiler's discretion, and may be null if the
compiler upholds condition #2; (2) adding any integer to the a pointer to a
zero-sized object yields a matching pointer; (3) subtracting two equal
pointers to zero-sized objects will yield an Unspecified integer.

In many cases, all a compiler would have to do to uphold those requirements
would simply be to check that array sizes were non-negative, rather than
checking whether they were greater than zero; except for the existence of
code that uses the aformentioned pattern for "static assertions" I don't
see any real disadvantage to such allowance.

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


#109863

Fromjoel.rees@gmail.com
Date2017-05-12 18:11 -0700
Message-ID<c0df6bc4-7d84-4a75-9644-f693af1b29d7@googlegroups.com>
In reply to#109842
On Saturday, May 13, 2017 at 12:46:56 AM UTC+9, supe...@casperkitty.com wrote:
> On Friday, May 12, 2017 at 8:17:46 AM UTC-5, joel...@gmail.com wrote:
> > Anyway, an array of one is most commonly a signal that you are 
> > allocating and using variable length arrays.
> 
> IMHO, the struct hack would have been cleaner in many ways had the authors
> of the Standard not opted to disallow arrays of size zero.  The only good
> reason I can see for disallowing such arrays would have been to ensure the
> correct "behavior" of a existing code that uses constructs like
> 
>     struct dummyName { int x[sizeof foo == 50]; };

#error was not good enough?

Fortunately, I think I have never seen code like that.

No, wait, I probably have, now that I think about it. But I'm going to 
admit to bias here and assert my opinion that code like that doesn't 
really deserve to be supported by the standard.

Unless the standard provided the support through an optional switch and 
the switch were off by default.

(I understood the reasons they didn't want those switches in the first 
version of the standard, but we need them now, for all sorts of things.)

> as a form of compile-time assertion.  I recognize that requiring compilers
> to accept arrays of size zero [before the Standard, some did and some did
> not] could have silently undermined what could be important compile-time
> safety checks, but given that compilers would be allowed to warn about
> zero-size arrays even if the Stanard allowed them, and could have offered
> a non-conforming mode that would break the build on such declarations, I
> would not think that would have been a major issue.
> 
> Otherwise, I think it would have been useful to allow zero-size objects
> with the privisos that:
> 
> (1) the address of a stand-alone zero-size object may or may not match the
> address of any other, at the compiler's discretion, and may be null if the
> compiler upholds condition #2; (2) adding any integer to the a pointer to a
> zero-sized object yields a matching pointer; (3) subtracting two equal
> pointers to zero-sized objects will yield an Unspecified integer.
> 
> In many cases, all a compiler would have to do to uphold those requirements
> would simply be to check that array sizes were non-negative, rather than
> checking whether they were greater than zero; except for the existence of
> code that uses the aformentioned pattern for "static assertions" I don't
> see any real disadvantage to such allowance.

I think I'm somewhat in agreement there, but I don't have to check how much.

--
Joel Rees

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

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


#109864

FromKeith Thompson <kst-u@mib.org>
Date2017-05-12 18:37 -0700
Message-ID<lnr2zt5ygo.fsf@kst-u.example.com>
In reply to#109863
joel.rees@gmail.com writes:
> On Saturday, May 13, 2017 at 12:46:56 AM UTC+9, supe...@casperkitty.com wrote:
[...]
>> IMHO, the struct hack would have been cleaner in many ways had the
>> authors of the Standard not opted to disallow arrays of size zero.
>> The only good reason I can see for disallowing such arrays would have
>> been to ensure the correct "behavior" of a existing code that uses
>> constructs like
>> 
>>     struct dummyName { int x[sizeof foo == 50]; };
>
> #error was not good enough?

#error didn't exist until C99, if I recall correctly.

[...]

> Unless the standard provided the support through an optional switch and 
> the switch were off by default.

The standard doesn't mention switches.  There are some optional
features, but they're provided at the option of the implementation, not
of the user.

[...]

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


#109895

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-13 09:44 -0700
Message-ID<kfnlgq0so40.fsf@x-alumni2.alumni.caltech.edu>
In reply to#109864
Keith Thompson <kst-u@mib.org> writes:

> joel.rees@gmail.com writes:
>> On Saturday, May 13, 2017 at 12:46:56 AM UTC+9,
>>  {} supe...@casperkitty.com wrote:
>
> [...]
>
>>> IMHO, the struct hack would have been cleaner in many ways had the
>>> authors of the Standard not opted to disallow arrays of size zero.
>>> The only good reason I can see for disallowing such arrays would have
>>> been to ensure the correct "behavior" of a existing code that uses
>>> constructs like
>>>
>>>     struct dummyName { int x[sizeof foo == 50]; };
>>
>> #error was not good enough?
>
> #error didn't exist until C99, if I recall correctly.

C89/C90 has #error.  What might be confusing you is that in
C99 #error requires compilation to fail, whereas in C89/C90
all that is required is a diagnostic.  In practical terms
I expect there is no difference, but the requirements are
slightly different in the two cases.  In both cases though
a diagnostic is required.

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


#109907

FromKeith Thompson <kst-u@mib.org>
Date2017-05-13 13:47 -0700
Message-ID<lnmvag5vrv.fsf@kst-u.example.com>
In reply to#109895
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> joel.rees@gmail.com writes:
[...]
>>> #error was not good enough?
>>
>> #error didn't exist until C99, if I recall correctly.
>
> C89/C90 has #error.

Quite right.  I should have checked before posting.  (I wish I had a
PDF copy of the C90 standard that wasn't scanned from a paper copy.
"ansi.c.txt", a draft of the ANSI C89 standard, is useful for quick
checks like this.)

>                      What might be confusing you is that in
> C99 #error requires compilation to fail, whereas in C89/C90
> all that is required is a diagnostic.

No, I was simply wrong about when #error was introduced.  I wasn't
aware of that difference until you mentioned it.

>                                        In practical terms
> I expect there is no difference, but the requirements are
> slightly different in the two cases.  In both cases though
> a diagnostic is required.

It's interesting that the C90 version of #error seems similar to the
#warning directive, a common non-standard extension (and one that I
wouldn't mind being standardized).  But as far as I know, in most C90
compilers #error causes compilation to fail, something that's not
implied by the description in the standard.

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


#109931

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-05-14 00:28 -0500
Message-ID<n8qfhc99t9lpvjqm8991cd0e6gjeo46mr5@4ax.com>
In reply to#109907
On Sat, 13 May 2017 13:47:32 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>>> joel.rees@gmail.com writes:
>[...]
>>>> #error was not good enough?
>>>
>>> #error didn't exist until C99, if I recall correctly.
>>
>> C89/C90 has #error.
>
>Quite right.  I should have checked before posting.  (I wish I had a
>PDF copy of the C90 standard that wasn't scanned from a paper copy.
>"ansi.c.txt", a draft of the ANSI C89 standard, is useful for quick
>checks like this.)
>
>>                      What might be confusing you is that in
>> C99 #error requires compilation to fail, whereas in C89/C90
>> all that is required is a diagnostic.
>
>No, I was simply wrong about when #error was introduced.  I wasn't
>aware of that difference until you mentioned it.
>
>>                                        In practical terms
>> I expect there is no difference, but the requirements are
>> slightly different in the two cases.  In both cases though
>> a diagnostic is required.
>
>It's interesting that the C90 version of #error seems similar to the
>#warning directive, a common non-standard extension (and one that I
>wouldn't mind being standardized).  But as far as I know, in most C90
>compilers #error causes compilation to fail, something that's not
>implied by the description in the standard.


I don't believe C89 actually requires compilation to fail in *any*
circumstance, just that a diagnostic be issued if certain rules are
violated.  C99 specifies one (IIRC) condition in which compilation
must fail (use of #error), but it doesn't actually define what failure
means ("The implementation shall not successfully translate a
preprocessing translation unit containing a #error preprocessing
directive...").

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


#109977

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-14 13:39 -0700
Message-ID<kfna86fqil4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#109907
Keith Thompson <kst-u@mib.org> writes:

> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>>> joel.rees@gmail.com writes:
>
> [...]
>
>>>> #error was not good enough?
>>>
>>> #error didn't exist until C99, if I recall correctly.
>>
>> C89/C90 has #error.
>
> Quite right.  I should have checked before posting.  (I wish I had a
> PDF copy of the C90 standard that wasn't scanned from a paper copy.
> "ansi.c.txt", a draft of the ANSI C89 standard, is useful for quick
> checks like this.)
>
>>                      What might be confusing you is that in
>> C99 #error requires compilation to fail, whereas in C89/C90
>> all that is required is a diagnostic.
>
> No, I was simply wrong about when #error was introduced.  I wasn't
> aware of that difference until you mentioned it.
>
>>                                        In practical terms
>> I expect there is no difference, but the requirements are
>> slightly different in the two cases.  In both cases though
>> a diagnostic is required.
>
> It's interesting that the C90 version of #error seems similar to the
> #warning directive, a common non-standard extension (and one that I
> wouldn't mind being standardized).

Personally I think the directive being named #error already makes
it different enough from #warning that the behaviors may be
expected to be different, even if the stated semantics for #error
doesn't require them to be so.

> But as far as I know, in most C90
> compilers #error causes compilation to fail, something that's not
> implied by the description in the standard.

To me, just naming the directive #error is enough to imply that
the compilation will fail, and I would be surprised by any
implementation that didn't.  To be clear, I agree with what you
are saying (or at least what I think you're saying), and don't
mean to say otherwise - my comment is related but is not meant to
be in opposition.

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


#110017

Fromraltbos@xs4all.nl (Richard Bos)
Date2017-05-15 13:02 +0000
Message-ID<5919a663.18985343@news.xs4all.nl>
In reply to#109977
Tim Rentsch <txr@alumni.caltech.edu> wrote:

> Keith Thompson <kst-u@mib.org> writes:
> 
> > But as far as I know, in most C90
> > compilers #error causes compilation to fail, something that's not
> > implied by the description in the standard.
> 
> To me, just naming the directive #error is enough to imply that
> the compilation will fail, and I would be surprised by any
> implementation that didn't.

So would I - #4.4 says, literally:

  The implementation shall not successfully translate a preprocessing
  translation unit containing a #error preprocessing directive unless it
  is part of a group skipped by conditional inclusion.

If compilation doesn't fail, surely that is the same thing as saying
that the TU _was_ translated successfully?

Richard

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


#110036

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-05-15 07:30 -0700
Message-ID<kfnefvqnqen.fsf@x-alumni2.alumni.caltech.edu>
In reply to#110017
raltbos@xs4all.nl (Richard Bos) writes:

> Tim Rentsch <txr@alumni.caltech.edu> wrote:
>
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> But as far as I know, in most C90
>>> compilers #error causes compilation to fail, something that's not
>>> implied by the description in the standard.
>>
>> To me, just naming the directive #error is enough to imply that
>> the compilation will fail, and I would be surprised by any
>> implementation that didn't.
>
> So would I - #4.4 says, literally:
>
>   The implementation shall not successfully translate a preprocessing
>   translation unit containing a #error preprocessing directive unless it
>   is part of a group skipped by conditional inclusion.
>
> If compilation doesn't fail, surely that is the same thing as saying
> that the TU _was_ translated successfully?

The quoted passage appears in C99 but does not appear in C90.
In C90 encountering a #error requires issuing a diagnostic,
but strictly speaking not more than that.

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


#109865

Fromsupercat@casperkitty.com
Date2017-05-12 20:45 -0700
Message-ID<30336eaa-f8e2-4f4b-beb9-896e90ffb824@googlegroups.com>
In reply to#109863
On Friday, May 12, 2017 at 8:11:37 PM UTC-5, joel...@gmail.com wrote:
> On Saturday, May 13, 2017 at 12:46:56 AM UTC+9, supercat wrote:
> > IMHO, the struct hack would have been cleaner in many ways had the authors
> > of the Standard not opted to disallow arrays of size zero.  The only good
> > reason I can see for disallowing such arrays would have been to ensure the
> > correct "behavior" of a existing code that uses constructs like
> > 
> >     struct dummyName { int x[sizeof foo == 50]; };
> 
> #error was not good enough?

Even on compilers which support #error (it was added in C99, but some
compilers supported it before that) it is limited to squawking about things
understood by the preprocessor.  There would be no way to have an #error
directive squawk if something is the wrong size because the preprocessor
has no clue about structure sizes, and the main processor won't get to do
anything unless all #error directives are eliminated at the preprocessor
stage.

Using array sizes as a form of static assert is icky, but the Standard does
not really provide much direct alternative.  On some compilers, a statement
like

   if (!condition) { 
     extern void something_bad_happened(void); 
     something_bad_happened();
   }

will lead to a linker squawk if no function of the indicated name exists
and the compiler can't prove that condition is definitely true, but on some
implementations such code would generate a linker squawk regardless.  MY
preference is to use some variation of the array-dimension trick but use
an expression that always evaluates to a positive value or a negative value
and doesn't rely upon any particular behavior with an array size of zero.
While I don't know to what extent the existence of code that uses array
sizes as assertions was a factor in the decision to disallow zero-sized
objects, I can't think of any other advantage to disallowing them.

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


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

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


csiph-web