Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Multi-dimension array assignments

Reply
Thread Tools

Multi-dimension array assignments

 
 
Eric Laberge
Guest
Posts: n/a
 
      08-22-2005
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.56 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.120, 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
 
Reply With Quote
 
 
 
 
Artie Gold
Guest
Posts: n/a
 
      08-22-2005
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.56 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.120, 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!"
 
Reply With Quote
 
 
 
 
Robert Gamble
Guest
Posts: n/a
 
      08-22-2005
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.56 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.120, 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

 
Reply With Quote
 
Dave Thompson
Guest
Posts: n/a
 
      08-27-2005
On Sun, 21 Aug 2005 21:12:58 -0400, Eric Laberge
<(E-Mail Removed)> 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.120, 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Array assignments Mike Java 3 06-06-2006 04:41 PM
Back-Annotate Assignments ALuPin VHDL 1 10-20-2004 09:21 PM
Using aggregates for assignments Gary Thorpe VHDL 4 06-15-2004 03:33 PM
Concurrent assignments to std_ulogic_vector slice is OK with ModelSim Nicolas Matringe VHDL 9 06-14-2004 10:10 PM
using entity attributes for pin number assignments Neil Zanella VHDL 2 10-26-2003 03:22 AM



Advertisments