Array assignment conundrum

L

Lionel B

Hi,

I am trying to get my head around this:

int main()
{
typedef int array1[3];

array1 x,y;
y = x; // error: invalid array assignment

struct array2
{
array1 x;
};

array2 a,b;
b = a; // OK, assigns b.x element-wise from a.x
}

Now for array2, since no assignment op is defined, as I understand it a
default assignment op will be invoked which simply assigns individual
members of struct array2... but the only member of array2 is an array1...
which cannot be assigned. What is happening here?
 
N

Neelesh Bodas

Hi,

I am trying to get my head around this:

int main()
{
typedef int array1[3];

array1 x,y;
y = x; // error: invalid array assignment

because array name is not a modifiable lvalue.
struct array2
{
array1 x;
};

array2 a,b;
b = a; // OK, assigns b.x element-wise from a.x

yes. This is same as saying
b[0] = a[0];
b[1] = a[1];
b[2] = a[2]
}

Now for array2, since no assignment op is defined, as I understand it a
default assignment op will be invoked which simply assigns individual
members of struct array2... but the only member of array2 is an array1...
which cannot be assigned. What is happening here?

You are not assigning to an array. you are assigning to array members.
That is perfectly allowed.

-N
 
L

Lionel B

Hi,

I am trying to get my head around this:

int main()
{
typedef int array1[3];

array1 x,y;
y = x; // error: invalid array assignment

because array name is not a modifiable lvalue.
Ok.
struct array2
{
array1 x;
};

array2 a,b;
b = a; // OK, assigns b.x element-wise from a.x

yes. This is same as saying
b[0] = a[0];
b[1] = a[1];
b[2] = a[2]

Yes, so it seems. My question was: *why*?

(BTW I assume you meant:

b.x[0] = a.x[0];
b.x[1] = a.x[1];
b.x[2] = a.x[2];

since array2 doesn't have an operator[] )
You are not assigning to an array. you are assigning to array members.
That is perfectly allowed.

I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...
 
D

dasjotre

Hi,
I am trying to get my head around this:
int main()
{
typedef int array1[3];
array1 x,y;
y = x; // error: invalid array assignment
because array name is not a modifiable lvalue.
Ok.
yes. This is same as saying
b[0] = a[0];
b[1] = a[1];
b[2] = a[2]

Yes, so it seems. My question was: *why*?

(BTW I assume you meant:

b.x[0] = a.x[0];
b.x[1] = a.x[1];
b.x[2] = a.x[2];

since array2 doesn't have an operator[] )
You are not assigning to an array. you are assigning to array members.
That is perfectly allowed.

I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...

according to [12.8.8]

"The implicitly-defined copy constructor for class
X performs a memberwise copy of its subobjects."
....
"- if the subobject is an array, each element is copied,
in the manner appropriate to the element type;"

regards

DS
 
L

Lionel B

I am trying to get my head around this:
int main()
{
typedef int array1[3];
array1 x,y;
y = x; // error: invalid array assignment
because array name is not a modifiable lvalue.
Ok.

struct array2
{
array1 x;
};
array2 a,b;
b = a; // OK, assigns b.x element-wise from a.x
yes. This is same as saying
b[0] = a[0];
b[1] = a[1];
b[2] = a[2]

Yes, so it seems. My question was: *why*?

(BTW I assume you meant:

b.x[0] = a.x[0];
b.x[1] = a.x[1];
b.x[2] = a.x[2];

since array2 doesn't have an operator[] )
Now for array2, since no assignment op is defined, as I understand
it a default assignment op will be invoked which simply assigns
individual members of struct array2... but the only member of array2
is an array1... which cannot be assigned. What is happening here?
You are not assigning to an array. you are assigning to array
members. That is perfectly allowed.

I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...
according to [12.8.8]

"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ...
"- if the subobject is an array, each element is copied, in the manner
appropriate to the element type;"

Ah, cheers. That's it then.

I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?
 
J

Jim Langston

Lionel B said:
On Mon, 16 Jul 2007 02:49:45 -0700, Neelesh Bodas wrote:
Hi,

I am trying to get my head around this:

int main()
{
typedef int array1[3];

array1 x,y;
y = x; // error: invalid array assignment

because array name is not a modifiable lvalue.

Ok.

struct array2
{
array1 x;
};

array2 a,b;
b = a; // OK, assigns b.x element-wise from a.x

yes. This is same as saying
b[0] = a[0];
b[1] = a[1];
b[2] = a[2]

Yes, so it seems. My question was: *why*?

(BTW I assume you meant:

b.x[0] = a.x[0];
b.x[1] = a.x[1];
b.x[2] = a.x[2];

since array2 doesn't have an operator[] )

}

Now for array2, since no assignment op is defined, as I understand
it a default assignment op will be invoked which simply assigns
individual members of struct array2... but the only member of array2
is an array1... which cannot be assigned. What is happening here?

You are not assigning to an array. you are assigning to array
members. That is perfectly allowed.

I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...
according to [12.8.8]

"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ...
"- if the subobject is an array, each element is copied, in the manner
appropriate to the element type;"

Ah, cheers. That's it then.

I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?

The default copy constructor is sometimes refered to a "bitwise copy". The
data is copied across bit for bit with disreguard as to what they actually
contain. This is not totally true, however. If an object in a
structure/class has it's own default copy constructor, that desturctor will
be called, which is why things like std::string and std::vector get copy
constructed corretly using a default constructor. However, for base types
(pointers, ints, arrays, etc...) they are just copied bit for bit.

That is why your array gets copied corretly.
 
L

Lionel B

Lionel B said:
On Mon, 16 Jul 2007 02:49:45 -0700, Neelesh Bodas wrote:
I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...


according to [12.8.8]

"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ... "- if the subobject is an
array, each element is copied, in the manner appropriate to the
element type;"

Ah, cheers. That's it then.

I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?

The default copy constructor is sometimes refered to a "bitwise copy".
The data is copied across bit for bit with disreguard as to what they
actually contain. This is not totally true, however. If an object in a
structure/class has it's own default copy constructor, that desturctor
will be called, which is why things like std::string and std::vector get
copy constructed corretly using a default constructor. However, for
base types (pointers, ints, arrays, etc...) they are just copied bit for
bit.

That is why your array gets copied corretly.

Cheers, yes, I understand that. What I meant to say was: "is there any
good reason why non-member arrays might not also be bitwise copyable?" -
aside from the fact that the standard doesn't allow for it.
 
J

Jim Langston

Lionel B said:
Lionel B said:
On Mon, 16 Jul 2007 03:34:02 -0700, dasjotre wrote:

On Mon, 16 Jul 2007 02:49:45 -0700, Neelesh Bodas wrote:
I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...


according to [12.8.8]

"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ... "- if the subobject is an
array, each element is copied, in the manner appropriate to the
element type;"

Ah, cheers. That's it then.

I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?

The default copy constructor is sometimes refered to a "bitwise copy".
The data is copied across bit for bit with disreguard as to what they
actually contain. This is not totally true, however. If an object in a
structure/class has it's own default copy constructor, that desturctor
will be called, which is why things like std::string and std::vector get
copy constructed corretly using a default constructor. However, for
base types (pointers, ints, arrays, etc...) they are just copied bit for
bit.

That is why your array gets copied corretly.

Cheers, yes, I understand that. What I meant to say was: "is there any
good reason why non-member arrays might not also be bitwise copyable?" -
aside from the fact that the standard doesn't allow for it.

What if you wanted to do this?

char Foo[] = "ABCDE";
char* Bar = Foo;

Or:


void FooBar( char* parm1, char* parm2 )
{
parm1 = parm2;
}

int main()
{
char Foo[] = "ABCDE";
char* Bar = Foo;

FooBar( Foo, Bar );
}

How is FooBar supposed to know if they are arrays and if to copy them
element by elemet or not?

And what if you passed them as char parm1[], char parm2[], how is FooBar
supposed to know their size?

A lot of time you may have an array without knowing it's size, so it
wouldn't be possible.
 
L

Lionel B

Lionel B said:
On Mon, 16 Jul 2007 03:34:02 -0700, dasjotre wrote:

]
I still don't get it. Eg.

struct astruct
{
int i;
};

astruct a,b;
b = a

will do:

b.i = a.i;

By the same logic, I'd have thought:

array2 a,b;
b = a;

would attempt to do:

b.x = a.x;

but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...


according to [12.8.8]

"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ... "- if the subobject is an
array, each element is copied, in the manner appropriate to the
element type;"

Ah, cheers. That's it then.

I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?

The default copy constructor is sometimes refered to a "bitwise copy".
The data is copied across bit for bit with disreguard as to what they
actually contain. This is not totally true, however. If an object in
a structure/class has it's own default copy constructor, that
desturctor will be called, which is why things like std::string and
std::vector get copy constructed corretly using a default constructor.
However, for base types (pointers, ints, arrays, etc...) they are
just copied bit for bit.

That is why your array gets copied corretly.

Cheers, yes, I understand that. What I meant to say was: "is there any
good reason why non-member arrays might not also be bitwise copyable?"
- aside from the fact that the standard doesn't allow for it.

What if you wanted to do this?

char Foo[] = "ABCDE";
char* Bar = Foo;

Or:


void FooBar( char* parm1, char* parm2 ) {
parm1 = parm2;
}

[...]

Yup, say no more.

Cheers,
 
D

dasjotre

Lionel B said:
34:02 -0700, dasjotre wrote:
]
I still don't get it. Eg.
struct astruct
{
int i;
};
astruct a,b;
b = a
will do:
b.i = a.i;
By the same logic, I'd have thought:
array2 a,b;
b = a;
would attempt to do:
b.x = a.x;
but since b.x, a.x are arrays - and therefore non-assignable - this
should not be permissable...
according to [12.8.8]
"The implicitly-defined copy constructor for class X performs a
memberwise copy of its subobjects." ... "- if the subobject is an
array, each element is copied, in the manner appropriate to the
element type;"
Ah, cheers. That's it then.
I wonder why, though, that being the case, that element-wise copy
shouldn't apply also to non-class member arrays...?
The default copy constructor is sometimes refered to a "bitwise copy".
The data is copied across bit for bit with disreguard as to what they
actually contain. This is not totally true, however. If an object in
a structure/class has it's own default copy constructor, that
desturctor will be called, which is why things like std::string and
std::vector get copy constructed corretly using a default constructor.
However, for base types (pointers, ints, arrays, etc...) they are
just copied bit for bit.
That is why your array gets copied corretly.
Cheers, yes, I understand that. What I meant to say was: "is there any
good reason why non-member arrays might not also be bitwise copyable?"
- aside from the fact that the standard doesn't allow for it.
What if you wanted to do this?
char Foo[] = "ABCDE";
char* Bar = Foo;

void FooBar( char* parm1, char* parm2 ) {
parm1 = parm2;
}

[...]

Yup, say no more.

in C array to pointer degradation is compulsory
for all expressions of array type except in
few cases such as sizeof or char str[] = "str"
the pointer you get from the conversion can
only be rvalue.

AFAIK C++ copied that rule from C with some
C++ specific exceptions (references,
implicit copy).

regards

DS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top