Unnamed compound object as "buffer" arguments

Discussion in 'C Programming' started by Eric Laberge, Sep 4, 2005.

  1. Eric Laberge

    Eric Laberge Guest

    Aloha!

    This question is meant to be about C99 and unnamed compound objects. As I
    read, if such a construct as
    int *p = (int[]){0};
    is used within a function, then it has "automatic storage duration
    associated with the enclosing block".

    So I tried the annexed code, and it compiles without a warning, and works as
    I expected.

    I'm mostly puzzled by the object lifetime, ie.: if I can reasonably use such
    a construct for temporary initialisation, by passing it as a function
    parameter and then memcpy'ing it to another variable. By it being declared
    as a function parameter, is this function the "enclosing block" and as such
    I will lose the ability to correctly pass it's pointer back to memcpy, or
    is its scope the entire "main" function?

    Before somebody asks why I don't directly call "myfunc" with "a" or "b" as
    parameters, I'm trying to chain some array-modifying functions together,
    and mostly simply experimenting some stuff.

    Thanks, I like reading this group.

    /* BOF */
    /* Tried with "gcc -std=c99 -pedantic -Wall file.c" */
    #include <stdio.h>
    #include <string.h>

    unsigned int* myfunc(unsigned int* buffer)
    {
    unsigned int i;

    for (i = 0; i < 5; i++)
    buffer = i;

    return buffer;
    }

    int main(void)
    {
    unsigned int a[5];
    unsigned int b[5];
    unsigned int i;

    memcpy(a, myfunc((unsigned int[5]){0}), sizeof a);
    memcpy(b, myfunc((unsigned int[5]){0}), sizeof b);

    for (i = 0; i < 5; i++)
    printf("a[%d]=%d\tb[%d]=%d\n", i, a, i, b);

    return 0;
    }
    /* EOF */
    --
    Eric Laberge
    Eric Laberge, Sep 4, 2005
    #1
    1. Advertising

  2. Eric Laberge wrote:
    > Aloha!
    >
    > This question is meant to be about C99 and unnamed compound objects. As I
    > read, if such a construct as
    > int *p = (int[]){0};
    > is used within a function, then it has "automatic storage duration
    > associated with the enclosing block".
    >
    > So I tried the annexed code, and it compiles without a warning, and works as
    > I expected.
    >
    > I'm mostly puzzled by the object lifetime, ie.: if I can reasonably use such
    > a construct for temporary initialisation, by passing it as a function
    > parameter and then memcpy'ing it to another variable. By it being declared
    > as a function parameter, is this function the "enclosing block" and as such
    > I will lose the ability to correctly pass it's pointer back to memcpy, or
    > is its scope the entire "main" function?


    The storage duration of a compound literal at function scope is until
    the end of the block in which it appears. A function call does not
    constitute a block.

    > Before somebody asks why I don't directly call "myfunc" with "a" or "b" as
    > parameters, I'm trying to chain some array-modifying functions together,
    > and mostly simply experimenting some stuff.
    >
    > Thanks, I like reading this group.
    >
    > /* BOF */
    > /* Tried with "gcc -std=c99 -pedantic -Wall file.c" */
    > #include <stdio.h>
    > #include <string.h>
    >
    > unsigned int* myfunc(unsigned int* buffer)
    > {
    > unsigned int i;
    >
    > for (i = 0; i < 5; i++)
    > buffer = i;
    >
    > return buffer;
    > }
    >
    > int main(void)
    > {
    > unsigned int a[5];
    > unsigned int b[5];
    > unsigned int i;
    >
    > memcpy(a, myfunc((unsigned int[5]){0}), sizeof a);
    > memcpy(b, myfunc((unsigned int[5]){0}), sizeof b);


    The main function is the associated enclosing block, thus the storage
    duration of the two compound literals continues until the end of your
    main function.

    > for (i = 0; i < 5; i++)
    > printf("a[%d]=%d\tb[%d]=%d\n", i, a, i, b);
    >
    > return 0;
    > }
    > /* EOF */


    Robert Gamble
    Robert Gamble, Sep 5, 2005
    #2
    1. Advertising

  3. On Sun, 04 Sep 2005 17:01:59 -0400, Eric Laberge
    <> wrote:

    >Aloha!
    >
    >This question is meant to be about C99 and unnamed compound objects. As I
    >read, if such a construct as
    > int *p = (int[]){0};
    >is used within a function, then it has "automatic storage duration
    >associated with the enclosing block".
    >
    >So I tried the annexed code, and it compiles without a warning, and works as
    >I expected.
    >
    >I'm mostly puzzled by the object lifetime, ie.: if I can reasonably use such
    >a construct for temporary initialisation, by passing it as a function
    >parameter and then memcpy'ing it to another variable. By it being declared
    >as a function parameter, is this function the "enclosing block" and as such


    A function call does not create a block. The compound literal has
    automatic storage duration associated with the block of code it is
    defined in.

    >I will lose the ability to correctly pass it's pointer back to memcpy, or
    >is its scope the entire "main" function?
    >
    >Before somebody asks why I don't directly call "myfunc" with "a" or "b" as
    >parameters, I'm trying to chain some array-modifying functions together,
    >and mostly simply experimenting some stuff.
    >
    >Thanks, I like reading this group.
    >
    >/* BOF */
    >/* Tried with "gcc -std=c99 -pedantic -Wall file.c" */
    >#include <stdio.h>
    >#include <string.h>
    >
    >unsigned int* myfunc(unsigned int* buffer)
    >{
    > unsigned int i;
    >
    > for (i = 0; i < 5; i++)
    > buffer = i;
    >
    > return buffer;
    >}
    >
    >int main(void)
    >{
    > unsigned int a[5];
    > unsigned int b[5];
    > unsigned int i;
    >
    > memcpy(a, myfunc((unsigned int[5]){0}), sizeof a);


    The compound literal here has automatic duration for the life of main.

    > memcpy(b, myfunc((unsigned int[5]){0}), sizeof b);


    It is implementation defined whether this literal defines the same
    object as the previous one (similar to the situation for multiple
    occurrences of a string literal). Since myfunc doesn't use the
    current values in the array, the issue is moot here. If myfunc did
    use the original values, the first call would receive zeros but the
    second call could receive zeros or the results of the first call.

    >
    > for (i = 0; i < 5; i++)
    > printf("a[%d]=%d\tb[%d]=%d\n", i, a, i, b);
    >
    > return 0;
    >}
    >/* EOF */



    <<Remove the del for email>>
    Barry Schwarz, Sep 5, 2005
    #3
  4. Eric Laberge

    Kevin Bracey Guest

    In message <>
    Barry Schwarz <> wrote:

    > On Sun, 04 Sep 2005 17:01:59 -0400, Eric Laberge
    > <> wrote:
    >
    > > memcpy(a, myfunc((unsigned int[5]){0}), sizeof a);

    >
    > The compound literal here has automatic duration for the life of main.
    >
    > > memcpy(b, myfunc((unsigned int[5]){0}), sizeof b);

    >
    > It is implementation defined whether this literal defines the same
    > object as the previous one (similar to the situation for multiple
    > occurrences of a string literal). Since myfunc doesn't use the
    > current values in the array, the issue is moot here. If myfunc did
    > use the original values, the first call would receive zeros but the
    > second call could receive zeros or the results of the first call.


    Incorrect. Every compound literal has separate storage, and is a distinct
    object. The exception is for compound literals with const-qualified type -
    like string literals, compound literals need not be distinct objects (and you
    can't modify them).

    --
    Kevin Bracey, Principal Software Engineer
    Tematic Tel: +44 (0) 1223 503464
    3 Signet Court, Swann Road, Fax: +44 (0) 1223 503464
    Cambridge, CB5 8LA, United Kingdom WWW: http://www.tematic.com/
    Kevin Bracey, Sep 5, 2005
    #4
  5. Eric Laberge

    Flash Gordon Guest

    Kevin Bracey wrote:
    > In message <>
    > Barry Schwarz <> wrote:
    >
    >>On Sun, 04 Sep 2005 17:01:59 -0400, Eric Laberge
    >><> wrote:
    >>
    >>> memcpy(a, myfunc((unsigned int[5]){0}), sizeof a);

    >>
    >>The compound literal here has automatic duration for the life of main.
    >>
    >>> memcpy(b, myfunc((unsigned int[5]){0}), sizeof b);

    >>
    >>It is implementation defined whether this literal defines the same
    >>object as the previous one (similar to the situation for multiple
    >>occurrences of a string literal). Since myfunc doesn't use the
    >>current values in the array, the issue is moot here. If myfunc did
    >>use the original values, the first call would receive zeros but the
    >>second call could receive zeros or the results of the first call.

    >
    > Incorrect. Every compound literal has separate storage, and is a distinct
    > object. The exception is for compound literals with const-qualified type -
    > like string literals, compound literals need not be distinct objects (and you
    > can't modify them).


    String literals do *not* have a const-qualified type. The reason they
    "cannot" be modified is because the standard says modifying them invokes
    undefined behaviour (which means on some systems you will get away with
    it) and IIRC the standard explicitly allows them to share storage. I
    don't know about compound literals.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Sep 5, 2005
    #5
  6. In article <-gordon.me.uk>, Flash Gordon <> writes:
    > Kevin Bracey wrote:
    > >
    > > Incorrect. Every compound literal has separate storage, and is a distinct
    > > object. The exception is for compound literals with const-qualified type -
    > > like string literals, compound literals need not be distinct objects (and
    > > you can't modify them).

    >
    > String literals do *not* have a const-qualified type.


    Kevin didn't say they did; he said that compound literals of const-
    qualified type were like string literals in that they need not be
    distinct objects.

    What he wrote is not ambiguous if you understand the dash as
    separating two clauses - which is the preferred usage. You can only
    read "like string literals" as an appositive to "compound literals
    with const-qualified type" if you see the dash as separating two
    phrases in the same clause, which would be rather sloppy. (As Kevin
    wrote it, "like string literals" is an adjectival phrase in
    apposition to the phrase "compound literals need not be distinct
    objects".

    --
    Michael Wojcik

    Even 300 years later, you should plan it in detail, when it comes to your
    summer vacation. -- Pizzicato Five
    Michael Wojcik, Sep 7, 2005
    #6
  7. Eric Laberge

    Flash Gordon Guest

    Michael Wojcik wrote:
    > In article <-gordon.me.uk>, Flash Gordon <> writes:
    >
    >>Kevin Bracey wrote:
    >>
    >>>Incorrect. Every compound literal has separate storage, and is a distinct
    >>>object. The exception is for compound literals with const-qualified type -
    >>>like string literals, compound literals need not be distinct objects (and
    >>>you can't modify them).

    >>
    >>String literals do *not* have a const-qualified type.

    >
    > Kevin didn't say they did; he said that compound literals of const-
    > qualified type were like string literals in that they need not be
    > distinct objects.


    OK, I can accept that was his intent.

    > What he wrote is not ambiguous if you understand the dash as
    > separating two clauses - which is the preferred usage. You can only
    > read "like string literals" as an appositive to "compound literals
    > with const-qualified type" if you see the dash as separating two
    > phrases in the same clause, which would be rather sloppy. (As Kevin
    > wrote it, "like string literals" is an adjectival phrase in
    > apposition to the phrase "compound literals need not be distinct
    > objects".


    I'm always willing to learn, but my experience is that using a dash to
    separate two clauses is not very common. Using it to separate two
    phrases in the same clause is also not very common in my experience.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Sep 7, 2005
    #7
  8. In article <-gordon.me.uk>, Flash Gordon <> writes:
    > Michael Wojcik wrote:
    >
    > > What he wrote is not ambiguous if you understand the dash as
    > > separating two clauses - which is the preferred usage.

    >
    > I'm always willing to learn, but my experience is that using a dash to
    > separate two clauses is not very common.


    No? That's how I used it in the quoted text above - it's separating
    an independent clause from a dependent clause. And in the previous
    sentence it's separating two independent clauses.

    > Using it to separate two
    > phrases in the same clause is also not very common in my experience.


    That would be the only other option, in a normal English sentence.
    Sentences are composed of phrases. Any two adjacent phrases must
    either be in the same clause or in two adjacent clauses. (Note
    also that clauses are themselves phrases, and phrases can contain
    phrases.)

    So, if you have "X - Y", X and Y are by definition phrases, and
    the dash is separating them. (All of "X - Y" may also be a phrase,
    but within that phrase "X" and "Y" maintain their status as
    distinct (nested) phrases because they're separated by the dash.)
    Further, they're either in the same clause or not; and if not, those
    two clauses are obviously adjacent, so the dash is separating them.

    Among English stylists the dash seems generally to be regarded as
    having two preferred uses in ordinary prose: to set off short
    parenthetical (substituting for parentheses) or appositional (substi-
    tuting for commas) phrases, and to separate independent clauses
    (substituting for the semicolon or for a comma and coordinating
    conjunction). Tom Wolfe, for example, uses the former to excess;
    most good writers employ it sparingly.

    Of course, this has gotten entirely OT.

    --
    Michael Wojcik

    They had forgathered enough of course in all the various times; they had
    again and again, since that first night at the theatre, been face to face
    over their question; but they had never been so alone together as they were
    actually alone - their talk hadn't yet been so supremely for themselves.
    -- Henry James
    Michael Wojcik, Sep 9, 2005
    #8
    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. Mattia Belletti

    unnamed object creation

    Mattia Belletti, Oct 20, 2003, in forum: Java
    Replies:
    4
    Views:
    423
    Jason Us
    Oct 22, 2003
  2. Raja
    Replies:
    12
    Views:
    24,343
    John Harrison
    Jun 21, 2004
  3. Replies:
    2
    Views:
    587
    sergejusz
    Mar 26, 2007
  4. John
    Replies:
    0
    Views:
    447
  5. Neal Becker

    buffer creates only read-only buffer?

    Neal Becker, Jan 8, 2009, in forum: Python
    Replies:
    0
    Views:
    400
    Neal Becker
    Jan 8, 2009
Loading...

Share This Page