Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: Compatibility question (http://www.velocityreviews.com/forums/t953649-re-compatibility-question.html)

Ian Collins 10-20-2012 03:20 AM

Re: Compatibility question
 
On 10/20/12 16:08, Steve Thompson wrote:
> I have been using structures containing zero-length arrays as a means
> of combining descriptors and array data in a single allocation unit.
> Something like the following is a common idiom:
>
> struct foo {
> int a, b;
> size_t len;
> char p[0];
> };


That should really be

char p[];

Which is the standardised (as of C99) form of the struct hack.

> So far, so good. My questions regards the availability of zero-length
> arrays in common systems. That is, if I wish my code to be compatible
> with most C compilers in use today, should I worry about avoiding
> zero-length arrays, or is the feature old enough, with sufficient
> prevalence to make it's use reasonable in portable code?


Most compilers should support the standard form, or the zero length
array form of the struct hack.

--
Ian Collins

Ben Bacarisse 10-20-2012 10:50 AM

Re: Compatibility question
 
Ian Collins <ian-news@hotmail.com> writes:

> On 10/20/12 16:08, Steve Thompson wrote:
>> I have been using structures containing zero-length arrays as a means
>> of combining descriptors and array data in a single allocation unit.
>> Something like the following is a common idiom:
>>
>> struct foo {
>> int a, b;
>> size_t len;
>> char p[0];
>> };

>
> That should really be
>
> char p[];
>
> Which is the standardised (as of C99) form of the struct hack.
>
>> So far, so good. My questions regards the availability of zero-length
>> arrays in common systems. That is, if I wish my code to be compatible
>> with most C compilers in use today, should I worry about avoiding
>> zero-length arrays, or is the feature old enough, with sufficient
>> prevalence to make it's use reasonable in portable code?

>
> Most compilers should support the standard form, or the zero length
> array form of the struct hack.


Before C99, the usual form was a one-element array -- a small amount of
waste, but guaranteed to compile everywhere. A zero-length array is a
constraint violation so, of the three options (p[], p[1] and p[0]) it is
the most likely to give a compiler stomach ache.

Lots of part of C99 (such as // comments) are nearly ubiquitous, even in
the Microsoft world, but I don't know how wide-spread p[] is.

--
Ben.

Keith Thompson 10-20-2012 06:41 PM

Re: Compatibility question
 
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Ian Collins <ian-news@hotmail.com> writes:
>> On 10/20/12 16:08, Steve Thompson wrote:
>>> I have been using structures containing zero-length arrays as a means
>>> of combining descriptors and array data in a single allocation unit.
>>> Something like the following is a common idiom:
>>>
>>> struct foo {
>>> int a, b;
>>> size_t len;
>>> char p[0];
>>> };

>>
>> That should really be
>>
>> char p[];
>>
>> Which is the standardised (as of C99) form of the struct hack.
>>
>>> So far, so good. My questions regards the availability of zero-length
>>> arrays in common systems. That is, if I wish my code to be compatible
>>> with most C compilers in use today, should I worry about avoiding
>>> zero-length arrays, or is the feature old enough, with sufficient
>>> prevalence to make it's use reasonable in portable code?

>>
>> Most compilers should support the standard form, or the zero length
>> array form of the struct hack.

>
> Before C99, the usual form was a one-element array -- a small amount of
> waste, but guaranteed to compile everywhere. A zero-length array is a
> constraint violation so, of the three options (p[], p[1] and p[0]) it is
> the most likely to give a compiler stomach ache.
>
> Lots of part of C99 (such as // comments) are nearly ubiquitous, even in
> the Microsoft world, but I don't know how wide-spread p[] is.


Microsoft's C compiler, which is notorious for its lack of C99 support,
does support flexible array members -- but only if you enable "language
extensions". (I'm using Microsoft Visual C++ 2010 Express.)

So my advice is to go ahead and use the C99 feature p[] in preference to
either p[0] (which is a constraint violation in C90, C99, and C11) or
p[1] (which is a valid declaration, but accessing elements past p[0],
strictly speaking, has undefined behavior.)

If you're concerned about C90 compatility, you'll need to decide which
form is more portable *to the compilers you're using*.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Ian Collins 10-20-2012 08:26 PM

Re: Compatibility question
 
On 10/20/12 17:01, Steve Thompson wrote:
> On Sat, Oct 20, 2012 at 04:20:53PM +1300, Ian Collins wrote:
>> On 10/20/12 16:08, Steve Thompson wrote:
>>> I have been using structures containing zero-length arrays as a means
>>> of combining descriptors and array data in a single allocation unit.
>>> Something like the following is a common idiom:
>>>
>>> struct foo {
>>> int a, b;
>>> size_t len;
>>> char p[0];
>>> };

>>
>> That should really be
>>
>> char p[];
>>
>> Which is the standardised (as of C99) form of the struct hack.
>>
>>> So far, so good. My questions regards the availability of zero-length
>>> arrays in common systems. That is, if I wish my code to be compatible
>>> with most C compilers in use today, should I worry about avoiding
>>> zero-length arrays, or is the feature old enough, with sufficient
>>> prevalence to make it's use reasonable in portable code?

>>
>> Most compilers should support the standard form, or the zero length
>> array form of the struct hack.

>
> I was mainly wondering what the cutoff date was for this feature. If
> C compilers deployed within the last ten years or so support the p[0]
> idiom, I won't feel as if I'm excluding platforms that might otherwise
> be expected to run my code. The workaround is not a huge problem
> since the accesses will be insulated from the user by my functions,
> but it is less trouble to write if I don't have to cast everything.


As Ben pointed out, the pre-C99 form was a single element array. I
think the zero element array is a gcc extension. So if you really want
to support every possible compiler, use p[1] and document what you are
doing. Otherwise use the standard form.

--
Ian Collins

Ian Collins 10-21-2012 11:29 PM

Re: Compatibility question
 
On 10/22/12 11:54, Steve Thompson wrote:
> On Sun, Oct 21, 2012 at 09:26:54AM +1300, Ian Collins wrote:
>> On 10/20/12 17:01, Steve Thompson wrote:
>>> On Sat, Oct 20, 2012 at 04:20:53PM +1300, Ian Collins wrote:
>>>> On 10/20/12 16:08, Steve Thompson wrote:
>>>>> I have been using structures containing zero-length arrays as a means
>>>>> of combining descriptors and array data in a single allocation unit.
>>>>> Something like the following is a common idiom:
>>>>>
>>>>> struct foo {
>>>>> int a, b;
>>>>> size_t len;
>>>>> char p[0];
>>>>> };
>>>>
>>>> That should really be
>>>>
>>>> char p[];
>>>>
>>>> Which is the standardised (as of C99) form of the struct hack.
>>>>
>>>>> So far, so good. My questions regards the availability of zero-length
>>>>> arrays in common systems. That is, if I wish my code to be compatible
>>>>> with most C compilers in use today, should I worry about avoiding
>>>>> zero-length arrays, or is the feature old enough, with sufficient
>>>>> prevalence to make it's use reasonable in portable code?
>>>>
>>>> Most compilers should support the standard form, or the zero length
>>>> array form of the struct hack.
>>>
>>> I was mainly wondering what the cutoff date was for this feature. If
>>> C compilers deployed within the last ten years or so support the p[0]
>>> idiom, I won't feel as if I'm excluding platforms that might otherwise
>>> be expected to run my code. The workaround is not a huge problem
>>> since the accesses will be insulated from the user by my functions,
>>> but it is less trouble to write if I don't have to cast everything.

>>
>> As Ben pointed out, the pre-C99 form was a single element array. I
>> think the zero element array is a gcc extension. So if you really want
>> to support every possible compiler, use p[1] and document what you are
>> doing. Otherwise use the standard form.

>
> Working on another part of the software I'm writing, I learned today
> that I must use TLS. There is no point trying to get around that
> constraint, so the list of potential targets is going to shrink quite
> a lot.


Times Literary Supplement?

> Now that I've noticed that the GCC documentation has been updated (I
> may not have read that section for ten years, now that I think of it),
> it does indeed say that the C99 standard includes support for flexible
> arrays, with similar semantics to the old gcc zero subscript hack, so
> I will use that.


You can't use a VLA as a structure member (how would you declare it?).

--
Ian Collins

Ben Bacarisse 10-22-2012 01:27 AM

Re: Compatibility question
 
Steve Thompson <stevet810@gmail.com> writes:

> On Mon, Oct 22, 2012 at 12:29:08PM +1300, Ian Collins wrote:
>> On 10/22/12 11:54, Steve Thompson wrote:

<snip>
>> >Now that I've noticed that the GCC documentation has been updated (I
>> >may not have read that section for ten years, now that I think of it),
>> >it does indeed say that the C99 standard includes support for flexible
>> >arrays, with similar semantics to the old gcc zero subscript hack, so
>> >I will use that.

>>
>> You can't use a VLA as a structure member (how would you declare it?).

>
>>From the GCC info pages:

>
> In ISO C99, you would use a "flexible array member", which is slightly
> different in syntax and semantics:
>
> * Flexible array members are written as `contents[]' without the `0'.
>
> * Flexible array members have incomplete type, and so the `sizeof'
> operator may not be applied. As a quirk of the original
> implementation of zero-length arrays, `sizeof' evaluates to zero.
>
> * Flexible array members may only appear as the last member of a
> `struct' that is otherwise non-empty.
>
> * A structure containing a flexible array member, or a union
> containing such a structure (possibly recursively), may not be a
> member of a structure or an element of an array. (However, these
> uses are permitted by GCC as extensions.)
>
> So I'm free and clear. My VLAs will be in structures which are not
> encapsulated in other structures.


There's a terminology confusion here. Your flexible array member is
just that, it's not a VLA. Variable length arrays are not permitted in
structs and flexible array members can only appear, unsurprisingly, in a
struct.

--
Ben.

Keith Thompson 10-22-2012 02:27 AM

Re: Compatibility question
 
Steve Thompson <stevet810@gmail.com> writes:
[...]
>From the GCC info pages:
>
> In ISO C99, you would use a "flexible array member", which is slightly
> different in syntax and semantics:
>
> * Flexible array members are written as `contents[]' without the `0'.
>
> * Flexible array members have incomplete type, and so the `sizeof'
> operator may not be applied. As a quirk of the original
> implementation of zero-length arrays, `sizeof' evaluates to zero.
>
> * Flexible array members may only appear as the last member of a
> `struct' that is otherwise non-empty.
>
> * A structure containing a flexible array member, or a union
> containing such a structure (possibly recursively), may not be a
> member of a structure or an element of an array. (However, these
> uses are permitted by GCC as extensions.)
>
> So I'm free and clear. My VLAs will be in structures which are not
> encapsulated in other structures.


VLAs and flexible array members are two different things. A VLA
is an array with a non-constant size; a flexible array member is
a member of array type defined with "[]".

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Barry Schwarz 10-22-2012 03:27 AM

Re: Compatibility question
 
On Sun, 21 Oct 2012 23:04:16 +0000, Steve Thompson
<stevet810@gmail.com> wrote:

>On Sat, Oct 20, 2012 at 11:41:09AM -0700, Keith Thompson wrote:
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> > Ian Collins <ian-news@hotmail.com> writes:
>> >> On 10/20/12 16:08, Steve Thompson wrote:
>> >>> I have been using structures containing zero-length arrays as a means
>> >>> of combining descriptors and array data in a single allocation unit.
>> >>> Something like the following is a common idiom:
>> >>>
>> >>> struct foo {
>> >>> int a, b;
>> >>> size_t len;
>> >>> char p[0];
>> >>> };
>> >>
>> >> That should really be
>> >>
>> >> char p[];
>> >>
>> >> Which is the standardised (as of C99) form of the struct hack.
>> >>
>> >>> So far, so good. My questions regards the availability of zero-length
>> >>> arrays in common systems. That is, if I wish my code to be compatible
>> >>> with most C compilers in use today, should I worry about avoiding
>> >>> zero-length arrays, or is the feature old enough, with sufficient
>> >>> prevalence to make it's use reasonable in portable code?
>> >>
>> >> Most compilers should support the standard form, or the zero length
>> >> array form of the struct hack.
>> >
>> > Before C99, the usual form was a one-element array -- a small amount of
>> > waste, but guaranteed to compile everywhere. A zero-length array is a
>> > constraint violation so, of the three options (p[], p[1] and p[0]) it is
>> > the most likely to give a compiler stomach ache.
>> >
>> > Lots of part of C99 (such as // comments) are nearly ubiquitous, even in
>> > the Microsoft world, but I don't know how wide-spread p[] is.

>>
>> Microsoft's C compiler, which is notorious for its lack of C99 support,
>> does support flexible array members -- but only if you enable "language
>> extensions". (I'm using Microsoft Visual C++ 2010 Express.)
>>
>> So my advice is to go ahead and use the C99 feature p[] in preference to
>> either p[0] (which is a constraint violation in C90, C99, and C11) or
>> p[1] (which is a valid declaration, but accessing elements past p[0],
>> strictly speaking, has undefined behavior.)

>
>The p[1] form is a bit of an eyesore since the actual structure I am
>using may have its "data area" appended to the structure, or it may be
>somewhere else.


How could p[1] be any more of an eyesore than p[0] or p[]?

How does p[0] allow you to put the data area somewhere else?

--
Remove del for email

Eric Sosman 10-22-2012 03:18 PM

Re: Compatibility question
 
On 10/21/2012 10:28 PM, Steve Thompson wrote:
> On Mon, Oct 22, 2012 at 02:27:01AM +0100, Ben Bacarisse wrote:
>>
>> There's a terminology confusion here. Your flexible array member is
>> just that, it's not a VLA. Variable length arrays are not permitted in
>> structs and flexible array members can only appear, unsurprisingly, in a
>> struct.

>
> I suppose so. Simply stated, anytime I use "something foo[]", it will
> usually be at the end of a struct. Good enough?


No, not unless you delete "usually."

> Really, you ought to have read what I meant, rather than reading what I
> wrote.


If only the compiler would do so ...

--
Eric Sosman
esosman@comcast-dot-net.invalid

Ben Bacarisse 10-22-2012 04:30 PM

Re: Compatibility question
 
Steve Thompson <stevet810@gmail.com> writes:

> On Mon, Oct 22, 2012 at 02:27:01AM +0100, Ben Bacarisse wrote:
>> Steve Thompson <stevet810@gmail.com> writes:
>>
>> > On Mon, Oct 22, 2012 at 12:29:08PM +1300, Ian Collins wrote:
>> >> On 10/22/12 11:54, Steve Thompson wrote:

>> <snip>
>> >> >Now that I've noticed that the GCC documentation has been updated (I
>> >> >may not have read that section for ten years, now that I think of it),
>> >> >it does indeed say that the C99 standard includes support for flexible
>> >> >arrays, with similar semantics to the old gcc zero subscript hack, so
>> >> >I will use that.
>> >>
>> >> You can't use a VLA as a structure member (how would you declare it?).
>> >
>> >>From the GCC info pages:
>> >
>> > In ISO C99, you would use a "flexible array member", which is slightly
>> > different in syntax and semantics:
>> >
>> > * Flexible array members are written as `contents[]' without the `0'.
>> >
>> > * Flexible array members have incomplete type, and so the `sizeof'
>> > operator may not be applied. As a quirk of the original
>> > implementation of zero-length arrays, `sizeof' evaluates to zero.
>> >
>> > * Flexible array members may only appear as the last member of a
>> > `struct' that is otherwise non-empty.
>> >
>> > * A structure containing a flexible array member, or a union
>> > containing such a structure (possibly recursively), may not be a
>> > member of a structure or an element of an array. (However, these
>> > uses are permitted by GCC as extensions.)
>> >
>> > So I'm free and clear. My VLAs will be in structures which are not
>> > encapsulated in other structures.

>>
>> There's a terminology confusion here. Your flexible array member is
>> just that, it's not a VLA. Variable length arrays are not permitted in
>> structs and flexible array members can only appear, unsurprisingly, in a
>> struct.

>
> I suppose so. Simply stated, anytime I use "something foo[]", it will
> usually be at the end of a struct. Good enough?


Absolutely.

> Really, you ought to have read what I meant, rather than reading what I
> wrote.


But I did! I think it's clear from my message that I knew exactly what
you meant; but postings might be read by silent lurkers who could be
confused if this distinction was not made very clear. Think of it as a
public service announcement. I'm sorry if it annoyed you.

--
Ben.


All times are GMT. The time now is 09:14 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.