Re: Compatibility question

Discussion in 'C Programming' started by Ian Collins, Oct 20, 2012.

  1. Ian Collins

    Ian Collins Guest

    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
    Ian Collins, Oct 20, 2012
    #1
    1. Advertising

  2. Ian Collins <> 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.
    Ben Bacarisse, Oct 20, 2012
    #2
    1. Advertising

  3. Ben Bacarisse <> writes:
    > Ian Collins <> 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) <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"
    Keith Thompson, Oct 20, 2012
    #3
  4. Ian Collins

    Ian Collins Guest

    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, Oct 20, 2012
    #4
  5. Ian Collins

    Ian Collins Guest

    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
    Ian Collins, Oct 22, 2012
    #5
  6. Steve Thompson <> 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.
    Ben Bacarisse, Oct 22, 2012
    #6
  7. Steve Thompson <> 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) <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"
    Keith Thompson, Oct 22, 2012
    #7
  8. On Sun, 21 Oct 2012 23:04:16 +0000, Steve Thompson
    <> wrote:

    >On Sat, Oct 20, 2012 at 11:41:09AM -0700, Keith Thompson wrote:
    >> Ben Bacarisse <> writes:
    >> > Ian Collins <> 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
    Barry Schwarz, Oct 22, 2012
    #8
  9. Ian Collins

    Eric Sosman Guest

    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
    d
    Eric Sosman, Oct 22, 2012
    #9
  10. Steve Thompson <> writes:

    > On Mon, Oct 22, 2012 at 02:27:01AM +0100, Ben Bacarisse wrote:
    >> Steve Thompson <> 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.
    Ben Bacarisse, Oct 22, 2012
    #10
  11. Eric Sosman <> writes:

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


    That's overly restrictive, isn't it? something foo[] can legally appear
    in places other than at the end of a struct.

    He should, perhaps, have said "Simply stated, anytime I use 'something
    foo[]' in a struct, it will be at the end" but what he said is fine by
    me.

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

    >
    > If only the compiler would do so ...


    --
    Ben.
    Ben Bacarisse, Oct 22, 2012
    #11
  12. Ben Bacarisse <> writes:

    > Eric Sosman <> writes:
    >
    >> On 10/21/2012 10:28 PM, Steve Thompson wrote:

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

    >
    > That's overly restrictive, isn't it? something foo[] can legally appear
    > in places other than at the end of a struct.


    That's point's been made. I should have read to the end of the thread.
    Sorry for the noise...

    <snip>
    --
    Ben.
    Ben Bacarisse, Oct 22, 2012
    #12
  13. Steve Thompson <> writes:
    [...]
    > No annoyance taken, although now that I think of it it does show an
    > instance of overloaded semantics, which can be confusing. When I was
    > less experienced with C, I was confused by the fact that variables
    > defined as structures were not pointers:
    >
    > struct point {
    > int x, y, z;
    > };
    >
    > struct point a;
    >
    >
    > One cannot reference 'a' (as such) in an expression even though it is
    > a pointer in the implementation because C allows one to use structures
    > as arguments to a function. I'd never do that in my own code, but
    > some people may like the fact that they can pass complex data
    > structures around as if they were simple variables. I think it wastes
    > resources, but of course that is less of an issue today than it was
    > when C was first developed.


    I'm not sure what you mean when you say `a` "is a pointer in
    the implementation", especially after you mention "the fact that
    variables defined as structures were not pointers".

    Whatever you meant, the fact it that `a` *isn't* a pointer; it's
    the name of an object of type `struct point`, and the name `a`
    certainly can be used in an expression: as the LHS or RHS of an
    assignment, as a function argument, as an argument to `sizeof` or
    `&`, as the left operand of `.`, and probably in other ways that
    I haven't thought of. Of course `&a` is a pointer (not a pointer
    object, but an expression of pointer type).

    > These days I'm thinking more and more about cache-line usage, so I am
    > concerned with preserving the 'hotness' of my data. Copying
    > structures around a whole lot is hostile to this paradigm, so that is
    > one language feature I am happy to avoid.


    If a structure is smaller than a pointer, or not much bigger, it makes
    perfect sense to pass it around by value.

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Oct 22, 2012
    #13
  14. Steve Thompson <> writes:

    > On Mon, Oct 22, 2012 at 10:52:47AM -0700, Keith Thompson wrote:
    >> Steve Thompson <> writes:
    >> [...]
    >> > No annoyance taken, although now that I think of it it does show an
    >> > instance of overloaded semantics, which can be confusing. When I was
    >> > less experienced with C, I was confused by the fact that variables
    >> > defined as structures were not pointers:
    >> >
    >> > struct point {
    >> > int x, y, z;
    >> > };
    >> >
    >> > struct point a;
    >> >
    >> >
    >> > One cannot reference 'a' (as such) in an expression even though it is
    >> > a pointer in the implementation because C allows one to use structures
    >> > as arguments to a function. I'd never do that in my own code, but
    >> > some people may like the fact that they can pass complex data
    >> > structures around as if they were simple variables. I think it wastes
    >> > resources, but of course that is less of an issue today than it was
    >> > when C was first developed.

    >>
    >> I'm not sure what you mean when you say `a` "is a pointer in
    >> the implementation", especially after you mention "the fact that
    >> variables defined as structures were not pointers".

    >
    > Meaning that under the hood in the C compiler, 'a' is really a
    > pointer. The logic of the compiler causes it to use the structure
    > data as specified in the standard, but conceptually 'a' is still a
    > pointer to the data in the specific structure identified by 'a'. I
    > found it very confusing when I was learning C.


    I am not surprised. I would have found it totally baffling when I was
    learning C. I find it baffling even now, having learnt C!

    Whatever goes on under the hood (and I'd dispute that 'a' is "really a
    pointer") it's much easier to learn a language in its own terms, at
    least as far as that's possible.

    In C terms, 'a' names an object and 'a' is a (modifiable) lvalue
    expression, just as if it had been declared to be an int. trying to
    reconcile this with some model that says it's a pointer (when it isn't
    one) is bound to be confusing.

    <snip>
    --
    Ben.
    Ben Bacarisse, Oct 22, 2012
    #14
  15. Ian Collins

    Öö Tiib Guest

    On Monday, 22 October 2012 20:29:11 UTC+3, Steve Thompson wrote:
    > When I was
    > less experienced with C, I was confused by the fact that variables
    > defined as structures were not pointers:
    >
    > struct point {
    > int x, y, z;
    > };
    >
    > struct point a;
    >
    >
    > One cannot reference 'a' (as such) in an expression even though it is
    > a pointer in the implementation because C allows one to use structures
    > as arguments to a function.


    One can use 'a' as such in several expressions like '(void)a', '&a', 'sizeof(a)' and 'a.x'.

    > I'd never do that in my own code, but
    > some people may like the fact that they can pass complex data
    > structures around as if they were simple variables.


    Anything that contains less than 32 bytes of information is very small amount
    of data in modern PC and so is usually optimal to use it by value as whole
    instead of making dynamic memory allocations for it. Passing by value
    makes it impossible for callee to modify the data of caller so it is safer.
    That is especially important in situations of concurrency. It is safer
    to pass data between different threads copied, then each has his own copy
    and there can not be any race conditions.

    > I think it wastes resources, but of course that is less of an issue today
    > than it was when C was first developed.


    Dynamic memory management is what wastes most of resources these days. OOP
    languages like Java and C++ rely sometimes too heavily on dynamic allocations
    of little objects and that makes them inefficient when the whole amount of
    such data grows into very large. For example: just 1000 cycles within 1000
    cycles and little allocations/deallocations done in that inner cycle. That
    takes about 5 seconds. 1000 by 1000 is very little however these days.
    Everybody have gigabytes of memory, terabyte of hard drive and millions of pixels on screen.
    Öö Tiib, Oct 22, 2012
    #15
  16. Ian Collins

    James Kuyper Guest

    On 10/22/2012 05:23 PM, Öö Tiib wrote:
    > On Monday, 22 October 2012 20:29:11 UTC+3, Steve Thompson wrote:
    >> When I was
    >> less experienced with C, I was confused by the fact that variables
    >> defined as structures were not pointers:
    >>
    >> struct point {
    >> int x, y, z;
    >> };
    >>
    >> struct point a;
    >>
    >>
    >> One cannot reference 'a' (as such) in an expression even though it is
    >> a pointer in the implementation because C allows one to use structures
    >> as arguments to a function.

    >
    > One can use 'a' as such in several expressions like '(void)a', '&a', 'sizeof(a)' and 'a.x'.


    Also, given

    struct point b;

    'a' can be used in expressions like:

    a = b;
    b = a;
    James Kuyper, Oct 22, 2012
    #16
  17. Ian Collins

    BartC Guest

    "Steve Thompson" <> wrote in message
    news:...

    > When I was
    > less experienced with C, I was confused by the fact that variables
    > defined as structures were not pointers:
    >
    > struct point {
    > int x, y, z;
    > };
    >
    > struct point a;
    >
    >
    > One cannot reference 'a' (as such) in an expression even though it is
    > a pointer in the implementation because C allows one to use structures
    > as arguments to a function. I'd never do that in my own code, but
    > some people may like the fact that they can pass complex data
    > structures around as if they were simple variables. I think it wastes
    > resources, but of course that is less of an issue today than it was
    > when C was first developed.


    What about this struct:

    struct {
    char r,g,b,a;
    } c;

    It would be less efficient to pass a pointer to this value, than to pass the
    value itself (especially when the pointer could well be wider). Returning
    such a struct as a value from a function is also far simpler.

    In any case C gives you the choice of pass-by-value or pass-by-reference -
    for structs.

    (What confuses *me* in some languages (it seems most of them these days) is
    stuff like this:

    a=[10,20,30]
    b=a

    a[0]=9999 # modify a

    print a
    print b

    You modify a, and find that b has also changed! Yet if a and b were numbers,
    you could 'modify' a after b=a, and b is not affected!)

    This is pass-by-reference taken to extremes.

    --
    bartc
    BartC, Oct 22, 2012
    #17
  18. Ian Collins

    Ian Collins Guest

    On 10/23/12 10:23, Öö Tiib wrote:
    > On Monday, 22 October 2012 20:29:11 UTC+3, Steve Thompson wrote:
    >
    >> I'd never do that in my own code, but
    >> some people may like the fact that they can pass complex data
    >> structures around as if they were simple variables.

    >
    > Anything that contains less than 32 bytes of information is very small amount
    > of data in modern PC and so is usually optimal to use it by value as whole
    > instead of making dynamic memory allocations for it. Passing by value
    > makes it impossible for callee to modify the data of caller so it is safer.
    > That is especially important in situations of concurrency. It is safer
    > to pass data between different threads copied, then each has his own copy
    > and there can not be any race conditions.


    That is true, but you have to be careful what you are copying. Plain
    old data is fine, but if your struct contains pointers or something that
    shouldn't be copied such as a mutex, nasty things can happen.

    >> I think it wastes resources, but of course that is less of an issue today
    >> than it was when C was first developed.

    >
    > Dynamic memory management is what wastes most of resources these days. OOP
    > languages like Java and C++ rely sometimes too heavily on dynamic allocations
    > of little objects and that makes them inefficient when the whole amount of
    > such data grows into very large.


    Java more than C++. Dynamic allocations can be avoided in C++, but not
    Java.

    --
    Ian Collins
    Ian Collins, Oct 22, 2012
    #18
  19. Ian Collins

    Les Cargill Guest

    BartC wrote:
    > "Steve Thompson" <> wrote in message
    > news:...
    >
    >> When I was
    >> less experienced with C, I was confused by the fact that variables
    >> defined as structures were not pointers:
    >>
    >> struct point {
    >> int x, y, z;
    >> };
    >>
    >> struct point a;
    >>
    >>
    >> One cannot reference 'a' (as such) in an expression even though it is
    >> a pointer in the implementation because C allows one to use structures
    >> as arguments to a function. I'd never do that in my own code, but
    >> some people may like the fact that they can pass complex data
    >> structures around as if they were simple variables. I think it wastes
    >> resources, but of course that is less of an issue today than it was
    >> when C was first developed.

    >
    > What about this struct:
    >
    > struct {
    > char r,g,b,a;
    > } c;
    >
    > It would be less efficient to pass a pointer to this value, than to pass
    > the
    > value itself (especially when the pointer could well be wider). Returning
    > such a struct as a value from a function is also far simpler.
    >
    > In any case C gives you the choice of pass-by-value or pass-by-reference -
    > for structs.
    >
    > (What confuses *me* in some languages (it seems most of them these days)
    > is stuff like this:
    >
    > a=[10,20,30]
    > b=a
    >
    > a[0]=9999 # modify a
    >
    > print a
    > print b
    >
    > You modify a, and find that b has also changed! Yet if a and b were
    > numbers,
    > you could 'modify' a after b=a, and b is not affected!)
    >
    > This is pass-by-reference taken to extremes.
    >



    That's not too different from:

    short a[] = {10, 20, 30};
    short *b = a;

    ....

    --
    Les Cargill
    Les Cargill, Oct 22, 2012
    #19
  20. Ian Collins

    James Kuyper Guest

    On 10/22/2012 05:44 PM, BartC wrote:
    ....
    > (What confuses *me* in some languages (it seems most of them these days) is
    > stuff like this:
    >
    > a=[10,20,30]
    > b=a
    >
    > a[0]=9999 # modify a
    >
    > print a
    > print b
    >
    > You modify a, and find that b has also changed! Yet if a and b were numbers,
    > you could 'modify' a after b=a, and b is not affected!)
    >
    > This is pass-by-reference taken to extremes.


    I agree, but it's a viable choice, so long as the language also provides
    some mechanism for creating a copy of 'a' rather than a reference to
    'a'. Do each of the languages you're thinking of have some such mechanism?
    James Kuyper, Oct 22, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Raymond Lee

    Browser compatibility question

    Raymond Lee, Oct 13, 2003, in forum: HTML
    Replies:
    8
    Views:
    407
    Paul Goodwin
    Oct 16, 2003
  2. tom
    Replies:
    46
    Views:
    1,260
  3. bartek
    Replies:
    6
    Views:
    352
    bartek
    Apr 5, 2004
  4. Charles Prince
    Replies:
    0
    Views:
    330
    Charles Prince
    Dec 6, 2004
  5. Vincezo Ciaschini
    Replies:
    13
    Views:
    5,725
    Rapscallion
    Jun 10, 2005
Loading...

Share This Page