I was not able to carry out the below,
int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};
array2 = array1;
I got incompatible type error.
My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.
Regards,
Janus
> I was not able to carry out the below,
>
> int array1 = {{2,1},{1,0}};
> int array2 = {{3, 5},{7,9}};
>
> array2 = array1;
It is better to cut and paste (or similar). Neither array1 nor array2
is declared as an array so your example does illustrate what you were
doing.
> I got incompatible type error.
>
> My only saving grace was memcpy... Now, I would want somebody to
> explain why array to array copying failed.
There are lots of levels for such an explanation. The simplest is
that C is designed that way: arrays are not "assignable". Another is
slightly more technical: the name of an array is converted to a
pointer to its first element[1] so that both sides of what appears to
be an array assignment are, in fact, pointer valued expressions.
Worse, the one on the left is not a modifiable lvalue -- it is just a
value and you can't assign to such a thing. One could get more
technical still and explain it all in terms used by the language
standard, but I doubt that would help.
There are also other kinds of explanation that would explain why is C
designed this way, but I am not sure I fancy trying that one!
So, in short, C is just like that. You can't assign whole arrays and
you have to use something like memcpy instead.
[1] There are a few exceptions, but lets keep this simple.
--
Ben.
Yes. The implementation is obliged to issue a diagnostic message for any
program that contains any constraint violations. Your code violates this
constraint:
"An assignment operator shall have a modifiable lvalue as its left operand."
See 3.3.16 of C89, or the corresponding passage in C99. (I really,
really must put my copy of that document onto this laptop!)
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
Well spotted. I missed the omission of [] in the definitions...
> so your example does illustrate what you were
> doing.
...but on the other hand, I didn't miss the omission of "not" in your
reply! :-)
<snip>
FWIW, you can embed an array in a struct:
__________________________________________________
struct array
{
int buffer[4];
};
int
main(void)
{
struct array a1;
struct array a2 = { { 1, 2, 3, 4 } };
a1 = a2;
return 0;
}
__________________________________________________
You probably meant:
int array1[][2] = {{2, 1}, {1, 0}};
and so on.
> array2 = array1;
C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d\n", array1[i][j]);
}
}
> My only saving grace was memcpy...
How was memcpy() your saving grace??
The above loop just prints the values of array1. To copy it into
array2, something like the code below is needed.
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
array2[i][j] = array1[i][j];
}
}
This assumes that both arrays MAX elements for both dimensions, and
you want a simple element by element copy of the whole array. For
fancier scenarios, you'll have to adjust the parameters of the loop.
>There are lots of levels for such an explanation. The simplest is
>that C is designed that way: arrays are not "assignable". Another is
>slightly more technical: the name of an array is converted to a
>pointer to its first element[1] so that both sides of what appears to
>be an array assignment are, in fact, pointer valued expressions.
>Worse, the one on the left is not a modifiable lvalue -- it is just a
>value and you can't assign to such a thing.
You can see this last point by trying
*(int (*)[2][2])array2 = *(int (*)[2][2])array1;
which is still an error, even though you have succeeded in getting
hold of the array (as an lvalue) rather than a pointer to its first
element.
-- Richard
--
Please remember to mention me / in tapes you leave behind.
> janus wrote:
>> Hello All,
>>
>> I was not able to carry out the below,
>>
>> int array1 = {{2,1},{1,0}};
>> int array2 = {{3, 5},{7,9}};
>
> You probably meant:
>
> int array1[][2] = {{2, 1}, {1, 0}};
>
> and so on.
>
>> array2 = array1;
>
> C doesn't natively support assigning one array to another. You'll have
> to use a loop. For example:
>
> for (int i = 0; i < MAX; i++) {
> for (int j = 0; j < MAX; j++) {
> printf("%d\n", array1[i][j]);
> }
> }
[I note you correct this to a copy in another post]. This is, for
me, a messy way to do it. If either dimension changes (or, worse,
the number of dimensions) this code must be found and changed.
>> My only saving grace was memcpy...
>
> How was memcpy() your saving grace??
Maybe because memcpy(array2, array1, sizeof array2); does what is
wanted in a way that need not change if the array sizes do? Of course
it breaks on some changes (such as moving the code into a function)
but it does enough to be described as a solution even if you'd not go
so far as to call it a saving grace.
--
Ben.
> >> I was not able to carry out the below,
> >>
> >> int array1 = {{2,1},{1,0}};
> >> int array2 = {{3, 5},{7,9}};
> >> array2 = array1;
> >
> > C doesn't natively support assigning one array to another. You'll have
> > to use a loop. For example:
> >
> > for (int i = 0; i < MAX; i++) {
> > for (int j = 0; j < MAX; j++) {
> > printf("%d\n", array1[i][j]);
> > }
> > }
>
> [I note you correct this to a copy in another post]. This is, for
> me, a messy way to do it. If either dimension changes (or, worse,
> the number of dimensions) this code must be found and changed.
>
> >> My only saving grace was memcpy...
> >
> > How was memcpy() your saving grace??
>
> Maybe because memcpy(array2, array1, sizeof array2); does what is
> wanted in a way that need not change if the array sizes do? Of course
> it breaks on some changes (such as moving the code into a function)
> but it does enough to be described as a solution even if you'd not go
> so far as to call it a saving grace.
Yes, thanks for mentioning that. But memcpy() will also have to be
checked and modified, if necessary, when either array's size or
dimensions change.
Hmm... Unless I've missed your point, I don't agree. 6.3.2.1 p3
(which governs what either side of array2 = array1; means) also
applies to your expressions.
*(int (*)[2][2])array2 is
"an expression that has type 'array of type'"
so it
"is converted to an expression with type 'pointer to type' that
points to the initial element of the array object and is not an
lvalue"
in exactly the same way. At no point do you get hold of the array as
an lvalue. One could argue that there is an array lvalue there,
fleetingly, which immediately gets converted, but the standard does
not word it that way and, in any case, the same would be true of both
forms of the assignment.
--
Ben.
> Ben Bacarisse wrote:
>> santosh <santo...@gmail.com> writes:
<snip>
>> > C doesn't natively support assigning one array to another. You'll have
>> > to use a loop. For example:
>> >
>> > for (int i = 0; i < MAX; i++) {
>> > for (int j = 0; j < MAX; j++) {
[corrected:]
>> > array2[i][j] = array1[i][j];
>> > }
>> > }
<snip>
>> > How was memcpy() your saving grace??
>>
>> Maybe because memcpy(array2, array1, sizeof array2); does what is
>> wanted in a way that need not change if the array sizes do?
<snip>
> Yes, thanks for mentioning that. But memcpy() will also have to be
> checked and modified, if necessary, when either array's size or
> dimensions change.
I don't follow. Your "if necessary" means that your statement is
almost a tautology, but my point is that it is not necessary.
--
Ben.
> I was not able to carry out the below,
>
> int array1 = {{2,1},{1,0}};
> int array2 = {{3, 5},{7,9}};
>
> array2 = array1;
>
> I got incompatible type error.
Yes, so do I. That is a weird way to phrase that error.
Note that if the above is literally what you had in your code, you also
should have had warnings on the declaration of the "arrays". What you
have above are definitions of two _ints_, not two arrays of int. For
obvious reasons you cannot initialise an int to an array of int,
although AFAICT the excess initialisers are ignored. However, a good
compiler set to a decent warning level will warn.
If I correct that, however, I, too, get an error saying "incompatible
types in assignment" on the assignment. And that's an unclear way of
stating what the real problem is: you can't assign to an array.
> My only saving grace was memcpy... Now, I would want somebody to
> explain why array to array copying failed.
Because you cannot assign to an array. There's nothing really
incompatible about it - you simply cannot assign anything to a whole
array at once. You'll have to use
Richard
>Hmm... Unless I've missed your point, I don't agree. 6.3.2.1 p3
>(which governs what either side of array2 = array1; means) also
>applies to your expressions.
Oops, yes, you're right. I was misremembering.
int array1[2][2] = {{2,1},{1,0}};
int array2[2][2] = {{3, 5},{7,9}};
array2 = array1;
Hell on earth :) , I am sorry for that omission. Please bear with me.
> How was memcpy() your saving grace??
I did.
memcpy(array1, array2, sizeof(array2));
hope that helped.
C can't do assignments of arbitrary length, except for structs. If a
compatible struct is defined (and it just needs to have the same number of
bytes as the array), then the following is possible:
#include "stdio.h"
#include "stdlib.h"
typedef struct{int array[2][2];} intarray22;
int main(void) {
int array1[2][2] = {{10,20},{30,40}};
int array2[2][2] = {{0,0},{0,0}};
*(intarray22*)array2 = *(intarray22*)array1;
printf ("Array2 =
{{%d,%d},{%d,%d}}\n",array2[0][0],array2[0][1],array2[1][0],array2[1][1]);
}
--
Bartc
Nitpick: "and unions."
> C can't do assignments of arbitrary length, except for structs. If a
> compatible struct is defined (and it just needs to have the same number
> of bytes as the array), then the following is possible:
>
> #include "stdio.h"
> #include "stdlib.h"
>
> typedef struct{int array[2][2];} intarray22;
>
> int main(void) {
> int array1[2][2] = {{10,20},{30,40}};
> int array2[2][2] = {{0,0},{0,0}};
>
> *(intarray22*)array2 = *(intarray22*)array1;
Non-nitpick: I don't think this is guaranteed to work.
It is possible that sizeof(intarray22) > 2*2*sizeof(int) --
that is, your parenthetical remark might not hold. There
could be alignment problems, too.
--
Eric Sosman
eso...@ieee-dot-org.invalid
Standard C doesn't allow array assignments.
What have you got against...
memcpy(array2, array1, sizeof array2);
--
Peter
And maybe because memcpy() is likely to be at least twice as fast as the
other form.
In fact, some processors have a copy instruction in the instruction set that
will copy large blocks of memory at a time in one instruction. One of those
could get you a speedup of far more than 2X.
The 8086 MOVS and REP come to mind. I'm sure there are other examples. But
a clever compiler or asembly-language programmer is going to implement
memcpy() using such things.
http://home.comcast.net/~fbui/intel_m.html#movs
http://home.comcast.net/~fbui/intel_r.html#rep
Datesfat.