Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #109727 > unrolled thread
| Started by | fl <rxjwg98@gmail.com> |
|---|---|
| First post | 2017-05-10 19:12 -0700 |
| Last post | 2017-05-27 06:15 -0700 |
| Articles | 20 on this page of 68 — 16 participants |
Back to article view | Back to comp.lang.c
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 →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-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]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2017-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-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]
| From | "Patrick.Schluter" <Patrick.Schluter@free.fr> |
|---|---|
| Date | 2017-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]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2017-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-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]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2017-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-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