E
Eric Laberge
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,
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,