Multi-dimension array assignments

Discussion in 'C Programming' started by Eric Laberge, Aug 22, 2005.

  1. Eric Laberge

    Eric Laberge Guest

    Aloha!

    I've been reading the standard (May '05 draft, actually) and stumbled across
    this:
    6.7.1 Initialization
    §20 "If the aggregate or union contains elements or members that are
    aggregates or unions, these rules apply recursively to the subaggregates or
    contained unions. If the initializer of a subaggregate or contained union
    begins with a left brace, the initializers enclosed by that brace and its
    matching right brace initialize the elements or members of the subaggregate
    or the contained union. Otherwise, only enough initializers from the list
    are taken to account for the elements or members of the subaggregate or the
    ?rst member of the contained union; any remaining initializers are left to
    initialize the next element or member of the aggregate of which the current
    subaggregate or contained union is a part."

    Fine, so this mean it is actually OK to init a multi-dim array as
    short a[2][3] = {0,1,2,3,4,5};
    §26 Example 3 actually confirms that.

    Just in case someone would wonder, line 10 is valid according to section
    6.5.2.5§6 regarding "anonymous" compound literals.

    So I set up some test to try to learn more about these:
    /* 1 */ #include <stdio.h>
    /* 2 */ #include <string.h>
    /* 3 */
    /* 4 */ int main()
    /* 5 */ {
    /* 6 */ short a[2][3] = {0,1,2,3,4,5};
    /* 7 */ short b[6];
    /* 8 */ short c[6];
    /* 9 */ memcpy(b, a, sizeof b);
    /*10 */ memcpy(c, (int[2][3]){{0,1,2},{3,4,5}}, sizeof c);
    /*11 */ if (!memcmp(a, b, sizeof b)) printf("a = b\n");
    /*12 */ if (!memcmp(a, c, sizeof c)) printf("a = c\n");
    /*13 */ if (!memcmp(b, c, sizeof c)) printf("b = c\n");
    /*14 */ return 0;
    /*15 */ }

    Compiled with "gcc -std=c99 -pedantic -Wall file.c", it however complains
    that:
    file.c: In function `main':
    file.c:6: warning: missing braces around initializer
    file.c:6: warning: (near initialization for `a[0]')

    Running the program, I end up with all 3 arrays having the same values:
    a = b
    a = c
    b = c

    Here are a couple of questions:
    1) About the compiler warning, either 1) this is not in the official C99
    standard and is one of the proposed feature by the commitee or 2) gcc is
    wrongly complaining about esthetics (like it suggests double parentheses in
    assignations in conditionals), in which case this is off-topic here. Which
    one is it?

    2) Are lines 9 and 10 assignments logically equivalent (except of course
    that b != c)? My guess is "yes" as both are copying from a short[2][3]
    memory location. Given that line 6 construct is o.k by 6.7.1§20, this
    should mean that line 13 will always compare to 1, whether or not what I
    actually meant to be copied is what I got (see #3).

    3) Will b and/or c contain the array {0,1,2,3,4,5} after lines 9 and 10? My
    guess is "yes" as array members need to be contiguous in memory, so arrays
    of arrays members (ie.: 1-dim arrays) would also be contiguous in memory as
    they are arrays too. However, I'm not sure if there can be padding between
    (n-1)dimensional-array elements in (n)dimensional arrays, where n>1, in
    which case I would be wrong in my assumption.

    Thanks,
    --
    Eric Laberge
     
    Eric Laberge, Aug 22, 2005
    #1
    1. Advertising

  2. Eric Laberge

    Artie Gold Guest

    Eric Laberge wrote:
    > Aloha!
    >
    > I've been reading the standard (May '05 draft, actually) and stumbled across
    > this:
    > 6.7.1 Initialization
    > §20 "If the aggregate or union contains elements or members that are
    > aggregates or unions, these rules apply recursively to the subaggregates or
    > contained unions. If the initializer of a subaggregate or contained union
    > begins with a left brace, the initializers enclosed by that brace and its
    > matching right brace initialize the elements or members of the subaggregate
    > or the contained union. Otherwise, only enough initializers from the list
    > are taken to account for the elements or members of the subaggregate or the
    > ?rst member of the contained union; any remaining initializers are left to
    > initialize the next element or member of the aggregate of which the current
    > subaggregate or contained union is a part."
    >
    > Fine, so this mean it is actually OK to init a multi-dim array as
    > short a[2][3] = {0,1,2,3,4,5};
    > §26 Example 3 actually confirms that.
    >
    > Just in case someone would wonder, line 10 is valid according to section
    > 6.5.2.5§6 regarding "anonymous" compound literals.
    >
    > So I set up some test to try to learn more about these:
    > /* 1 */ #include <stdio.h>
    > /* 2 */ #include <string.h>
    > /* 3 */
    > /* 4 */ int main()
    > /* 5 */ {
    > /* 6 */ short a[2][3] = {0,1,2,3,4,5};
    > /* 7 */ short b[6];
    > /* 8 */ short c[6];
    > /* 9 */ memcpy(b, a, sizeof b);
    > /*10 */ memcpy(c, (int[2][3]){{0,1,2},{3,4,5}}, sizeof c);
    > /*11 */ if (!memcmp(a, b, sizeof b)) printf("a = b\n");
    > /*12 */ if (!memcmp(a, c, sizeof c)) printf("a = c\n");
    > /*13 */ if (!memcmp(b, c, sizeof c)) printf("b = c\n");
    > /*14 */ return 0;
    > /*15 */ }
    >
    > Compiled with "gcc -std=c99 -pedantic -Wall file.c", it however complains
    > that:
    > file.c: In function `main':
    > file.c:6: warning: missing braces around initializer
    > file.c:6: warning: (near initialization for `a[0]')
    >
    > Running the program, I end up with all 3 arrays having the same values:
    > a = b
    > a = c
    > b = c
    >
    > Here are a couple of questions:
    > 1) About the compiler warning, either 1) this is not in the official C99
    > standard and is one of the proposed feature by the commitee or 2) gcc is
    > wrongly complaining about esthetics (like it suggests double parentheses in
    > assignations in conditionals), in which case this is off-topic here. Which
    > one is it?


    A compiler may issue a warning about anything it likes. Literally.
    There are many completely legal constructs that many, if not most or
    all, compilers will warn about -- including, for example, using an
    assignment expression as the conditional in an `if' or `while'
    statement. Effectively it's asking, "Are you sure?"
    >
    > 2) Are lines 9 and 10 assignments logically equivalent (except of course
    > that b != c)? My guess is "yes" as both are copying from a short[2][3]
    > memory location. Given that line 6 construct is o.k by 6.7.1§20, this
    > should mean that line 13 will always compare to 1, whether or not what I
    > actually meant to be copied is what I got (see #3).
    >

    Yes.

    > 3) Will b and/or c contain the array {0,1,2,3,4,5} after lines 9 and 10? My
    > guess is "yes" as array members need to be contiguous in memory, so arrays
    > of arrays members (ie.: 1-dim arrays) would also be contiguous in memory as
    > they are arrays too. However, I'm not sure if there can be padding between
    > (n-1)dimensional-array elements in (n)dimensional arrays, where n>1, in
    > which case I would be wrong in my assumption.
    >

    There cannot. You are right.

    HTH and Cheers,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://goldsays.blogspot.com (new post 8/5)
    http://www.cafepress.com/goldsays
    "If you have nothing to hide, you're not trying!"
     
    Artie Gold, Aug 22, 2005
    #2
    1. Advertising

  3. Eric Laberge wrote:
    > Aloha!
    >
    > I've been reading the standard (May '05 draft, actually) and stumbled across
    > this:
    > 6.7.1 Initialization


    That's actually 6.7.8.

    > §20 "If the aggregate or union contains elements or members that are
    > aggregates or unions, these rules apply recursively to the subaggregates or
    > contained unions. If the initializer of a subaggregate or contained union
    > begins with a left brace, the initializers enclosed by that brace and its
    > matching right brace initialize the elements or members of the subaggregate
    > or the contained union. Otherwise, only enough initializers from the list
    > are taken to account for the elements or members of the subaggregate or the
    > ?rst member of the contained union; any remaining initializers are left to
    > initialize the next element or member of the aggregate of which the current
    > subaggregate or contained union is a part."
    >
    > Fine, so this mean it is actually OK to init a multi-dim array as
    > short a[2][3] = {0,1,2,3,4,5};
    > §26 Example 3 actually confirms that.
    >
    > Just in case someone would wonder, line 10 is valid according to section
    > 6.5.2.5§6 regarding "anonymous" compound literals.
    >
    > So I set up some test to try to learn more about these:
    > /* 1 */ #include <stdio.h>
    > /* 2 */ #include <string.h>
    > /* 3 */
    > /* 4 */ int main()


    Should be "int main (void)"

    > /* 5 */ {
    > /* 6 */ short a[2][3] = {0,1,2,3,4,5};
    > /* 7 */ short b[6];
    > /* 8 */ short c[6];
    > /* 9 */ memcpy(b, a, sizeof b);
    > /*10 */ memcpy(c, (int[2][3]){{0,1,2},{3,4,5}}, sizeof c);
    > /*11 */ if (!memcmp(a, b, sizeof b)) printf("a = b\n");
    > /*12 */ if (!memcmp(a, c, sizeof c)) printf("a = c\n");
    > /*13 */ if (!memcmp(b, c, sizeof c)) printf("b = c\n");
    > /*14 */ return 0;
    > /*15 */ }
    >
    > Compiled with "gcc -std=c99 -pedantic -Wall file.c", it however complains
    > that:
    > file.c: In function `main':
    > file.c:6: warning: missing braces around initializer
    > file.c:6: warning: (near initialization for `a[0]')
    >
    > Running the program, I end up with all 3 arrays having the same values:
    > a = b
    > a = c
    > b = c
    >
    > Here are a couple of questions:
    > 1) About the compiler warning, either 1) this is not in the official C99
    > standard and is one of the proposed feature by the commitee or 2) gcc is
    > wrongly complaining about esthetics (like it suggests double parentheses in
    > assignations in conditionals), in which case this is off-topic here. Which
    > one is it?


    Neither. The official C99 document contains the verbiage you provided
    above, the code is conforming. Compilers are allowed to complain about
    whatever they like so long as the compile a conforming program. The
    authors of gcc apparently feel that a warning is warranted here.

    > 2) Are lines 9 and 10 assignments logically equivalent (except of course
    > that b != c)? My guess is "yes" as both are copying from a short[2][3]
    > memory location. Given that line 6 construct is o.k by 6.7.1§20, this
    > should mean that line 13 will always compare to 1, whether or not what I
    > actually meant to be copied is what I got (see #3).


    Correct.

    > 3) Will b and/or c contain the array {0,1,2,3,4,5} after lines 9 and 10? My
    > guess is "yes" as array members need to be contiguous in memory, so arrays
    > of arrays members (ie.: 1-dim arrays) would also be contiguous in memory as
    > they are arrays too. However, I'm not sure if there can be padding between
    > (n-1)dimensional-array elements in (n)dimensional arrays, where n>1, in
    > which case I would be wrong in my assumption.


    Your guess is correct, padding between array members is not allowed. A
    multidimensional array is really just an array of arrays in C. Padding
    is not allowed between the members of an array so there cannot be
    padding between the arrays that are themselves members of an array.

    Robert Gamble
     
    Robert Gamble, Aug 22, 2005
    #3
  4. On Sun, 21 Aug 2005 21:12:58 -0400, Eric Laberge
    <> wrote:

    <snip>
    > /* 6 */ short a[2][3] = {0,1,2,3,4,5};
    > /* 7 */ short b[6];
    > /* 8 */ short c[6];
    > /* 9 */ memcpy(b, a, sizeof b);
    > /*10 */ memcpy(c, (int[2][3]){{0,1,2},{3,4,5}}, sizeof c);

    <snip>
    > Compiled with "gcc -std=c99 -pedantic -Wall file.c", it however complains
    > that:
    > file.c: In function `main':
    > file.c:6: warning: missing braces around initializer
    > file.c:6: warning: (near initialization for `a[0]')

    <snip>
    > Here are a couple of questions:
    > 1) About the compiler warning, either 1) this is not in the official C99
    > standard and is one of the proposed feature by the commitee or 2) gcc is
    > wrongly complaining about esthetics (like it suggests double parentheses in
    > assignations in conditionals), in which case this is off-topic here. Which
    > one is it?
    >

    Yes, partially-braced initializers are standard in both C89/90 and C99
    and this gcc warning is just esthetics; whether it's wrong is, like
    all esthetics, a matter of taste. DGND. (Aside: we call them
    'assignment', 'assignment operator', etc., not 'assignation'.)

    > 2) Are lines 9 and 10 assignments logically equivalent (except of course
    > that b != c)? My guess is "yes" as both are copying from a short[2][3]
    > memory location. Given that line 6 construct is o.k by 6.7.1§20, this
    > should mean that line 13 will always compare to 1, whether or not what I
    > actually meant to be copied is what I got (see #3).
    >

    You actually posted int[2][3] in line 10; _that_ could be different.
    If you make it short[2][3] then yes they are the same, except that
    your program could make other references/accesses to a, but not to the
    compound literal since you don't save/have its address anywhere.

    > 3) Will b and/or c contain the array {0,1,2,3,4,5} after lines 9 and 10? My
    > guess is "yes" as array members need to be contiguous in memory, so arrays
    > of arrays members (ie.: 1-dim arrays) would also be contiguous in memory as
    > they are arrays too. However, I'm not sure if there can be padding between
    > (n-1)dimensional-array elements in (n)dimensional arrays, where n>1, in
    > which case I would be wrong in my assumption.
    >

    As others have said, yes, arrays are contiguous at all ranks.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Aug 27, 2005
    #4
    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. Adam Hartshorne

    Multi-Dimension Array Question

    Adam Hartshorne, Jun 8, 2005, in forum: C++
    Replies:
    6
    Views:
    2,162
  2. Makiyo
    Replies:
    3
    Views:
    544
    Richard Heathfield
    Feb 22, 2004
  3. Replies:
    11
    Views:
    538
    Alexei A. Frounze
    Sep 29, 2005
  4. Replies:
    12
    Views:
    610
    Thad Smith
    Oct 10, 2005
  5. Luuk
    Replies:
    15
    Views:
    884
    Nobody
    Feb 11, 2010
Loading...

Share This Page