469,568 Members | 1,435 Online

# Multi-dimension array assignments

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.

/* 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
Nov 15 '05 #1
3 2346
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.

/* 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!"
Nov 15 '05 #2
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.

/* 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

Nov 15 '05 #3
On Sun, 21 Aug 2005 21:12:58 -0400, Eric Laberge
<de********@myrealbox.com> 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
Nov 15 '05 #4

### This discussion thread is closed

Replies have been disabled for this discussion.