References in C

Discussion in 'C Programming' started by jacob navia, Jun 24, 2011.

  1. jacob navia

    jacob navia Guest

    The lcc-win compiler is an experimental compiler to promote the
    development of C as a language. Contrary to the main trends of language
    design this days, lcc-win considers C not a dead language but a language
    that can evolve and propose new features.

    In this context, one of the extensions that lcc-win supports is
    references, where the design is largely inspired from the C++ design.


    What are references?

    In fact, a reference is just a pointer. It is different from plain
    pointers in two ways:

    (1) It is always assigned to a concrete object when it is defined.
    (2) Once defined, it will always point to that same object. It can't
    be changed to point into another object.
    (3) It is used with the '.' notation, as if it weren't a pointer.
    (4) Instead of "*' the symbol "&" is used:
    int i = 23;
    int &IntReference = i;

    As always in this proposals, the problems hide in the details. For
    instance, several days ago someone complained that a reference to
    void would not compile, but a pointer to void would. This prompted
    me to correct a problem in my implementation: I should have forbidden to
    build references to void!

    The problem is when defining a reference but when you pass a reference
    to a function:
    int fn(void &ref);
    In this case there is no initialization (that would explode immediately)
    but just a definition without any initialization. The compiler must
    check, then, that the reference is not to a void pointer.

    Since the object pointed to by a reference can't change, many people
    think that the value can't never change but that is wrong. Consider:

    #include <stdio.h>
    int main(void)
    {
    int i = 23;
    int &pi = i;

    i = 3;
    printf("%d\n",pi);
    }

    The reference is initialized to an integer whose value is 23.
    If the integer changes its value, the reference (like all other
    pointers) changes its value also.

    The advantages of using references are that they are never NULL,
    and that they always point to the same object, two important
    things less to test. The only (orthodox) way of declaring a non-NULL
    pointer in an argument list is now:

    int fn(int arg[static 1]);

    This declares that the "arg" argument will have at least one integer
    Few people know this, and it wasn't much explained when C99 introduced
    it.

    jacob
    jacob navia, Jun 24, 2011
    #1
    1. Advertising

  2. jacob navia

    BGB Guest

    On 6/24/2011 1:42 AM, jacob navia wrote:
    > The lcc-win compiler is an experimental compiler to promote the
    > development of C as a language. Contrary to the main trends of language
    > design this days, lcc-win considers C not a dead language but a language
    > that can evolve and propose new features.
    >
    > In this context, one of the extensions that lcc-win supports is
    > references, where the design is largely inspired from the C++ design.
    >


    a partial risk though is that C + bunches-of-extensions is no longer C,
    rather, another C derived language (in a similar manner to C++ or
    Objective-C, which are also not strictly C).


    >
    > What are references?
    >
    > In fact, a reference is just a pointer. It is different from plain
    > pointers in two ways:
    >
    > (1) It is always assigned to a concrete object when it is defined.
    > (2) Once defined, it will always point to that same object. It can't
    > be changed to point into another object.
    > (3) It is used with the '.' notation, as if it weren't a pointer.
    > (4) Instead of "*' the symbol "&" is used:
    > int i = 23;
    > int &IntReference = i;
    >
    > As always in this proposals, the problems hide in the details. For
    > instance, several days ago someone complained that a reference to
    > void would not compile, but a pointer to void would. This prompted
    > me to correct a problem in my implementation: I should have forbidden to
    > build references to void!
    >
    > The problem is when defining a reference but when you pass a reference
    > to a function:
    > int fn(void &ref);
    > In this case there is no initialization (that would explode immediately)
    > but just a definition without any initialization. The compiler must
    > check, then, that the reference is not to a void pointer.
    >
    > Since the object pointed to by a reference can't change, many people
    > think that the value can't never change but that is wrong. Consider:
    >
    > #include <stdio.h>
    > int main(void)
    > {
    > int i = 23;
    > int &pi = i;
    >
    > i = 3;
    > printf("%d\n",pi);
    > }
    >
    > The reference is initialized to an integer whose value is 23.
    > If the integer changes its value, the reference (like all other
    > pointers) changes its value also.
    >
    > The advantages of using references are that they are never NULL,
    > and that they always point to the same object, two important
    > things less to test. The only (orthodox) way of declaring a non-NULL
    > pointer in an argument list is now:
    >
    > int fn(int arg[static 1]);
    >
    > This declares that the "arg" argument will have at least one integer
    > Few people know this, and it wasn't much explained when C99 introduced
    > it.
    >


    going OT:

    interestingly, in my own current language (more closely related to
    JavaScript and ActionScript), I ended up giving references a "look and
    feel" more like that of C pointers.

    basically, the caller needs to use "&" to pass an argument to a
    reference, and by default (no '&' in the argument list) it would be
    needed to use '*' to access/assign them. if '&' is given, it means to
    insert an implicit '*' on access, and later could also insert basic
    sanity checks (barf if the argument is not "sane" when calling the
    function).

    as-is, I figured doing calls like "foo(&x);" to be a reasonable
    trade-off (it serves a similar role to 'ref' in C#).

    note that, unlike C, these are not raw pointers, rather a
    boxed-pointer-type (some languages use the term "locative" for these
    instead of "pointer" or "reference").
    BGB, Jun 24, 2011
    #2
    1. Advertising

  3. jacob navia

    Ian Collins Guest

    On 06/24/11 09:53 PM, BGB wrote:
    > On 6/24/2011 1:42 AM, jacob navia wrote:
    >> The lcc-win compiler is an experimental compiler to promote the
    >> development of C as a language. Contrary to the main trends of language
    >> design this days, lcc-win considers C not a dead language but a language
    >> that can evolve and propose new features.
    >>
    >> In this context, one of the extensions that lcc-win supports is
    >> references, where the design is largely inspired from the C++ design.
    >>

    >
    > a partial risk though is that C + bunches-of-extensions is no longer C,
    > rather, another C derived language (in a similar manner to C++ or
    > Objective-C, which are also not strictly C).


    C++--?

    --
    Ian Collins
    Ian Collins, Jun 24, 2011
    #3
  4. jacob navia

    BartC Guest

    "jacob navia" <> wrote in message
    news:iu1iku$4k9$...

    > #include <stdio.h>
    > int main(void)
    > {
    > int i = 23;
    > int &pi = i;
    >
    > i = 3;
    > printf("%d\n",pi);
    > }


    This doesn't compile in my lcc-win32 unless I make i static ("addressable
    object required" in the int &pi line).

    Is this a restriction, or do I need an update?

    --
    Bartc
    BartC, Jun 24, 2011
    #4
  5. jacob navia

    Shao Miller Guest

    On 6/24/2011 04:42, jacob navia wrote:
    > The lcc-win compiler is an experimental compiler to promote the
    > development of C as a language. Contrary to the main trends of language
    > design this days, lcc-win considers C not a dead language but a language
    > that can evolve and propose new features.
    > ...
    > In fact, a reference is just a pointer. It is different from plain pointers in two ways:
    >
    > (1) It is always assigned to a concrete object when it is defined.
    > (2) Once defined, it will always point to that same object. It can't
    > be changed to point into another object.
    > (3) It is used with the '.' notation, as if it weren't a pointer.
    > (4) Instead of "*' the symbol "&" is used:
    > int i = 23;
    > int &IntReference = i;


    (I think you meant "four ways". You must have started with 2 and then
    remembered 2 more. ;) )

    So I'm guessing that if you have:

    void foo(struct xxx & bar) { /* ... */ }

    If you have an object with "allocated" storage duration, you'd do:

    struct xxx * bar;
    /* ...See below... */
    foo(*bar_ptr);

    in order for 'foo' to work with the pointed-to object, right?

    But before you perform the call, you must:
    - Allocate the object
    - Check that the allocation succeeds

    If you do these things before calling 'foo', then 'foo' needn't check
    for a null pointer, right? For:

    void foo(struct xxx * bar) { /* ... */ }

    "static" and "automatic" objects can have their addresses passed with
    '&', right?

    So this seems to be along the lines of #1, above.

    Then there's also:

    void foo(struct xxx * const bar) { /* ... */ }

    and:

    int i;
    int * const ip = &i;

    which appear to be along the lines of #2, above.

    Am I understanding these two points correctly?
    Shao Miller, Jun 24, 2011
    #5
  6. jacob navia

    Tom St Denis Guest

    On Jun 24, 4:42 am, jacob navia <> wrote:
    > The lcc-win compiler is an experimental compiler to promote the
    > development of C as a language. Contrary to the main trends of language
    > design this days, lcc-win considers C not a dead language but a language
    > that can evolve and propose new features.
    >
    > In this context, one of the extensions that lcc-win supports is
    > references, where the design is largely inspired from the C++ design.
    >
    > What are references?
    >
    > In fact, a reference is just a pointer. It is different from plain
    > pointers in two ways:
    >
    > (1) It is always assigned to a concrete object when it is defined.
    > (2) Once defined, it will always point to that same object. It can't
    >     be changed to point into another object.
    > (3) It is used with the '.' notation, as if it weren't a pointer.
    > (4) Instead of "*' the symbol "&" is used:
    >      int i = 23;
    >      int &IntReference = i;


    Simipler...

    int func(int *ledata)
    {
    #define reflefdata (*ledata)
    int a;

    a = (refledata *= 4);
    return a;
    }

    There, no more lazies.

    Also no language change required. You can do things like sizeof
    refledata, you can read/assign it, even take the address of it.

    Tom
    Tom St Denis, Jun 24, 2011
    #6
  7. On Jun 24, 9:48 am, Tom St Denis <> wrote:
    > Simipler...
    >
    > int func(int *ledata)
    > {
    > #define reflefdata (*ledata)
    >    int a;
    >
    >    a = (refledata *= 4);
    >    return a;
    >
    > }
    >
    > There, no more lazies.


    While I'm not sold on having references in C (not clear the it is THAT
    big a win), this macro crud isn't the same thing as having a ref.
    Main virtue of references is self-documentation and automated function
    argument semantics enforcement IMHO...

    i.e. in C you might have:

    /* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
    int func(int *ledata)
    {
    if ( ledata == NULL )
    {
    /* do something drastic */
    }
    }

    You can express all that extra material without the comments, checks,
    whatever, with the one little '&' in the

    int func( int &ledata )

    Earth shattering? No, but it is sometimes nice.

    -David
    David Resnick, Jun 24, 2011
    #7
  8. jacob navia

    jacob navia Guest

    Le 24/06/11 16:14, David Resnick a écrit :

    > While I'm not sold on having references in C (not clear the it is THAT
    > big a win), this macro crud isn't the same thing as having a ref.
    > Main virtue of references is self-documentation and automated function
    > argument semantics enforcement IMHO...
    >
    > i.e. in C you might have:
    >
    > /* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
    > int func(int *ledata)
    > {
    > if ( ledata == NULL )
    > {
    > /* do something drastic */
    > }
    > }
    >
    > You can express all that extra material without the comments, checks,
    > whatever, with the one little '&' in the
    >
    > int func( int&ledata )
    >
    > Earth shattering? No, but it is sometimes nice.
    >
    > -David


    Precisely. It is not the best thing since baked bread but it is an
    improvement that implies a small change in the language.
    jacob navia, Jun 24, 2011
    #8
  9. jacob navia

    jacob navia Guest

    Le 24/06/11 12:14, BartC a écrit :
    > "jacob navia" <> wrote in message
    > news:iu1iku$4k9$...
    >
    >> #include <stdio.h>
    >> int main(void)
    >> {
    >> int i = 23;
    >> int &pi = i;
    >>
    >> i = 3;
    >> printf("%d\n",pi);
    >> }

    >
    > This doesn't compile in my lcc-win32 unless I make i static
    > ("addressable object required" in the int &pi line).
    >
    > Is this a restriction, or do I need an update?
    >


    I think you need an update... I introduced this several years
    ago... I just compiled that and it works without any problems.

    Please do not use it with -ansic though.
    jacob navia, Jun 24, 2011
    #9
  10. jacob navia

    Tom St Denis Guest

    On Jun 24, 10:58 am, jacob navia <> wrote:
    > Le 24/06/11 16:14, David Resnick a écrit :
    >
    >
    >
    > > While I'm not sold on having references in C (not clear the it is THAT
    > > big a win), this macro crud isn't the same thing as having a ref.
    > > Main virtue of references is self-documentation and automated function
    > > argument semantics enforcement IMHO...

    >
    > > i.e. in C you might have:

    >
    > > /* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
    > > int func(int *ledata)
    > > {
    > >       if ( ledata == NULL )
    > >       {
    > >            /* do something drastic */
    > >       }
    > > }

    >
    > > You can express all that extra material without the comments, checks,
    > > whatever, with the one little '&' in the

    >
    > > int func( int&ledata )

    >
    > > Earth shattering?  No, but it is sometimes nice.

    >
    > > -David

    >
    > Precisely. It is not the best thing since baked bread but it is an
    > improvement that implies a small change in the language.


    I can't see a reason to not have it, but just the same I can't say
    that my programming career has been taking back by it. What I would
    love is Turbo Pascals "with" stmt. e.g.

    struct { int foo, bar, whatever; } baz;

    with (baz) {
    foo = 4;
    bar = 3 * foo;
    whatever = bar - 5;
    }

    Which makes all the elements of "baz" local scope. That would beat
    crap like

    baz.foo = 4;
    baz.bar = 3 * baz.foo;
    baz.whatever = baz.bar - 5;

    Of course then you have

    int foo;
    with (baz) {
    foo = 4; // which foo?
    }

    But that's something specifications are for...
    Tom St Denis, Jun 24, 2011
    #10
  11. jacob navia

    Ike Naar Guest

    On 2011-06-24, Tom St Denis <> wrote:
    > Simipler...
    >
    > int func(int *ledata)
    > {
    > #define reflefdata (*ledata)


    Error prone; see below.

    > int a;
    >
    > a = (refledata *= 4);


    See above.

    > return a;
    > }
    Ike Naar, Jun 24, 2011
    #11
  12. On 24-Jun-11 11:08, Tom St Denis wrote:
    > ... What I would love is Turbo Pascals "with" stmt. e.g.
    >
    > struct { int foo, bar, whatever; } baz;
    >
    > with (baz) {
    > foo = 4;
    > bar = 3 * foo;
    > whatever = bar - 5;
    > }
    >
    > Which makes all the elements of "baz" local scope. That would beat
    > crap like
    >
    > baz.foo = 4;
    > baz.bar = 3 * baz.foo;
    > baz.whatever = baz.bar - 5;
    >
    > Of course then you have
    >
    > int foo;
    > with (baz) {
    > foo = 4; // which foo?
    > }
    >
    > But that's something specifications are for...


    Presumably it would be baz.foo, using the same sort of logic as if the
    same identifier is used at block scope and file scope; you've just added
    a new level.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jun 24, 2011
    #12
  13. On 24-Jun-11 03:42, jacob navia wrote:
    > In fact, a reference is just a pointer. It is different from plain
    > pointers in two ways:
    >
    > (1) It is always assigned to a concrete object when it is defined.
    > (2) Once defined, it will always point to that same object. It can't
    > be changed to point into another object.
    > (3) It is used with the '.' notation, as if it weren't a pointer.
    > (4) Instead of "*' the symbol "&" is used:
    > int i = 23;
    > int &IntReference = i;


    More plainly, a reference is an implicitly dereferenced pointer. The
    compiler can substitute "(*ref)" wherever it sees "ref" and "ref"
    wherever it sees "&ref". Also, the address of the initializer is used
    rather than the initializer itself.

    > The problem is when defining a reference but when you pass a reference
    > to a function:
    > int fn(void &ref);
    > In this case there is no initialization (that would explode immediately)
    > but just a definition without any initialization. The compiler must
    > check, then, that the reference is not to a void pointer.


    Conceptually, when a function is called, its arguments are implicitly
    initialized with the corresponding parameters.

    > The advantages of using references are that they are never NULL,


    Well, there are circumstances where a reference could be null, but
    creating them requires invoking UB, so there's no point in specifying
    what happens after that point.

    > and that they always point to the same object, two important
    > things less to test.


    I'm not so sure about that. What is so wrong with being able to change
    the referent, e.g. by assigning to &ref?

    > The only (orthodox) way of declaring a non-NULL pointer in an argument
    > list is now:
    >
    > int fn(int arg[static 1]);
    >
    > This declares that the "arg" argument will have at least one integer
    > Few people know this, and it wasn't much explained when C99 introduced
    > it.


    News to me. Did we really need _yet another_ use for the "static" keyword?

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jun 24, 2011
    #13
  14. In article <>,
    Tom St Denis <> wrote:
    ....
    >Of course then you have
    >
    >int foo;
    >with (baz) {
    > foo = 4; // which foo?
    >}
    >
    >But that's something specifications are for...


    What does Pascal do?

    (But I agree with the other poster that it should be baz.foo, although I
    could easily imagine that it would be frequently desirable to be able to
    access the "uplevel" foo - something that ordinary "variable shadowing"
    prevents [unless extreme measures are taken...])

    --
    One of the best lines I've heard lately:

    Obama could cure cancer tomorrow, and the Republicans would be
    complaining that he had ruined the pharmaceutical business.

    (Heard on Stephanie Miller = but the sad thing is that there is an awful lot
    of direct truth in it. We've constructed an economy in which eliminating
    cancer would be a horrible disaster. There are many other such examples.)
    Kenny McCormack, Jun 24, 2011
    #14
  15. jacob navia

    jacob navia Guest

    Le 24/06/11 15:26, Shao Miller a écrit :
    > So I'm guessing that if you have:
    >
    > void foo(struct xxx & bar) { /* ... */ }
    >
    > If you have an object with "allocated" storage duration, you'd do:
    >
    > struct xxx * bar;
    > /* ...See below... */
    > foo(*bar_ptr);
    >
    > in order for 'foo' to work with the pointed-to object, right?
    >


    yes.


    > But before you perform the call, you must:
    > - Allocate the object
    > - Check that the allocation succeeds
    >


    Yes. You must pass an object, not a pointer.

    > If you do these things before calling 'foo', then 'foo' needn't check
    > for a null pointer, right? For:
    >
    > void foo(struct xxx * bar) { /* ... */ }
    >
    > "static" and "automatic" objects can have their addresses passed with
    > '&', right?
    >


    Yes. For immediate constants (foo(5);) the compiler must generate a
    temporary object and pass its address.


    > So this seems to be along the lines of #1, above.
    >
    > Then there's also:
    >
    > void foo(struct xxx * const bar) { /* ... */ }
    >
    > and:
    >
    > int i;
    > int * const ip = &i;
    >
    > which appear to be along the lines of #2, above.
    >
    > Am I understanding these two points correctly?


    I do not understand the second. Can you explain in more depth?
    jacob navia, Jun 24, 2011
    #15
  16. jacob navia

    Tom St Denis Guest

    On Jun 24, 12:08 pm, Ike Naar <> wrote:
    > On 2011-06-24, Tom St Denis <> wrote:
    >
    > > Simipler...

    >
    > > int func(int *ledata)
    > > {
    > > #define reflefdata (*ledata)

    >
    > Error prone; see below.
    >
    > >    int a;

    >
    > >    a = (refledata *= 4);

    >
    > See above.


    Error prone how? Aside from the typo which was easy enough to fix.
    If I have a complicated function in which I want to work on it by
    reference this is how I would do it. of course I'd switch the names
    around so the frequently used one was shorter...

    My error was akin to

    int foo(int &bar)
    {
    return (baz *= 3);
    }

    It's a friggin typo, not a design error.

    Tom
    Tom St Denis, Jun 24, 2011
    #16
  17. jacob navia <> writes:
    > Le 24/06/11 15:26, Shao Miller a écrit :
    >> So I'm guessing that if you have:
    >>
    >> void foo(struct xxx & bar) { /* ... */ }
    >>
    >> If you have an object with "allocated" storage duration, you'd do:
    >>
    >> struct xxx * bar;
    >> /* ...See below... */
    >> foo(*bar_ptr);
    >>
    >> in order for 'foo' to work with the pointed-to object, right?
    >>

    >
    > yes.

    [snip more questions and answers]

    Perhaps it would save time to explain how lcc-win's references differ
    from standard C++ references, if at all.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 24, 2011
    #17
  18. jacob navia

    Shao Miller Guest

    On 6/24/2011 14:08, jacob navia wrote:
    > Le 24/06/11 15:26, Shao Miller a écrit :
    >> So I'm guessing that if you have:
    >>
    >> void foo(struct xxx & bar) { /* ... */ }
    >>
    >> If you have an object with "allocated" storage duration, you'd do:
    >>
    >> struct xxx * bar;
    >> /* ...See below... */
    >> foo(*bar_ptr);
    >>
    >> in order for 'foo' to work with the pointed-to object, right?
    >>

    >
    > yes.
    >


    Thanks. :)

    >
    >> But before you perform the call, you must:
    >> - Allocate the object
    >> - Check that the allocation succeeds
    >>

    >
    > Yes. You must pass an object, not a pointer.
    >
    >> If you do these things before calling 'foo', then 'foo' needn't check
    >> for a null pointer, right? For:
    >>
    >> void foo(struct xxx * bar) { /* ... */ }
    >>
    >> "static" and "automatic" objects can have their addresses passed with
    >> '&', right?
    >>

    >
    > Yes. For immediate constants (foo(5);) the compiler must generate a
    > temporary object and pass its address.
    >


    Aha. I'm glad you brought this up. So, assuming the 'foo' above taking
    a pointer (not the one above that, taking an lcc-win reference), this is
    something that might be difficult with C89, but could be facilitated by C99:

    foo(&(int){5});

    >
    >> So this seems to be along the lines of #1, above.
    >>
    >> Then there's also:
    >>
    >> void foo(struct xxx * const bar) { /* ... */ }
    >>
    >> and:
    >>
    >> int i;
    >> int * const ip = &i;
    >>
    >> which appear to be along the lines of #2, above.
    >>
    >> Am I understanding these two points correctly?

    >
    > I do not understand the second. Can you explain in more depth?


    Well your point #2 was that references always refer to the same object.
    I'm asking if that's akin to 'ip', above. Does that make sense?
    Shao Miller, Jun 24, 2011
    #18
  19. jacob navia <> writes:
    > The lcc-win compiler is an experimental compiler to promote the
    > development of C as a language. Contrary to the main trends of
    > language design this days, lcc-win considers C not a dead language but
    > a language that can evolve and propose new features.
    >
    > In this context, one of the extensions that lcc-win supports is
    > references, where the design is largely inspired from the C++ design.
    >
    >
    > What are references?
    >
    > In fact, a reference is just a pointer. It is different from plain
    > pointers in two ways:
    >
    > (1) It is always assigned to a concrete object when it is defined.
    > (2) Once defined, it will always point to that same object. It can't
    > be changed to point into another object.
    > (3) It is used with the '.' notation, as if it weren't a pointer.
    > (4) Instead of "*' the symbol "&" is used:
    > int i = 23;
    > int &IntReference = i;

    [...]

    For what it's worth, an initialized const pointer gives you 2 and
    *partly* gives you 1, but not 3 or 4.

    The "partly" refers to the fact that an initialized local const
    pointer object, as long as the initialization isn't a null pointer,
    will always point to the same thing, but no such guarantees can be
    made for a pointer parameter unless you use the C99 "static" kludge.

    (This is an observation, not an argument for or against the
    proposal.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 24, 2011
    #19
  20. jacob navia

    Shao Miller Guest

    On 6/24/2011 04:42, jacob navia wrote:
    > The lcc-win compiler is an experimental compiler to promote the
    > development of C as a language. Contrary to the main trends of language
    > design this days, lcc-win considers C not a dead language but a language
    > that can evolve and propose new features.
    >
    > In this context, one of the extensions that lcc-win supports is
    > references, where the design is largely inspired from the C++ design.
    > ...


    Suppose I have the following C89:

    #include <assert.h>
    #include <stddef.h>

    #define ELEMENTS 5

    typedef double a_five_doubles[ELEMENTS];

    void foo(a_five_doubles array) {
    size_t i;

    /*
    * 'array' isn't an array, so
    * these probably aren't the same size
    */
    assert(
    sizeof array !=
    sizeof (a_five_doubles)
    );
    for (i = 0; i < ELEMENTS; ++i)
    array = 3.14159;
    return;
    }

    int main(void) {
    a_five_doubles array;

    foo(array);
    return 0;
    }

    Now suppose I have the following C89:

    #include <assert.h>
    #include <stddef.h>

    #define ELEMENTS 5

    typedef double a_five_doubles[ELEMENTS];

    void foo(a_five_doubles * array) {
    size_t i;

    /*
    * 'array' points to an array, so
    * these should be the same size
    */
    assert(
    sizeof *array ==
    sizeof (a_five_doubles)
    );
    for (i = 0; i < ELEMENTS; ++i)
    i[*array] = 3.14159;
    return;
    }

    int main(void) {
    a_five_doubles array;

    foo(&array);
    return 0;
    }

    If lcc-win references become standard C, if I have:

    #include <assert.h>
    #include <stddef.h>

    #define ELEMENTS 5
    #define COUNTOF(array) \
    (sizeof (array) / sizeof *(array))

    typedef double a_five_doubles[ELEMENTS];

    void foo(a_five_doubles & array) {
    size_t i;

    for (i = 0; i < COUNTOF(array); ++i)
    array = 3.14159;
    return;
    }

    int main(void) {
    a_five_doubles array;

    foo(array);
    return 0;
    }

    Does the 'for' loop execute five times? I'm guessing that C99's
    6.3.2.1p3 and 6.7.5.3p7 would need to be adjusted, right? (My C++
    memory for this is poor, I'm afraid, if that's relevant here.)
    Shao Miller, Jun 24, 2011
    #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. Roger Leigh
    Replies:
    8
    Views:
    420
    Karl Heinz Buchegger
    Nov 17, 2003
  2. Replies:
    3
    Views:
    437
    Victor Bazarov
    Nov 10, 2004
  3. DanielEKFA
    Replies:
    8
    Views:
    590
    DanielEKFA
    May 16, 2005
  4. Replies:
    8
    Views:
    696
    Bruno Desthuilliers
    Dec 12, 2006
  5. Lars Willich
    Replies:
    13
    Views:
    822
    Ian Shef
    Oct 23, 2007
Loading...

Share This Page