properties and assignment

P

Peter Bromley

I have been reading about the proposed changes for C++/CLI and they look
great. There is one thing that currently does not work well that I would
like clarified.

A managed C++ property can be assigned or accessed using the get_ and
set_ members, actions which generally work as one would expect

int a = MyIntProp; // calls get_
MyIntProp = 10; // calls set_

But, a natural C++ idiom is chained assignment, something which does not
work with properties as defined now.

int a = MyIntProp = 10; // error C2440: '=' : cannot convert from
'void' to 'double'
MyIntProp = a = 10; // OK

This problems extents to += and other operators (Note that the += itself
is presently coded as a get_ followed by a set_).

a = MyIntProp += 10; // error

The problem here appears to be that the compiler is not creating an
additional get_ call for chained operators, ie as if I wrote:

int a = MyIntProp, MyIntProp = 10; // for first error

or

a = MyIntProp, MyIntProp += 10; // for second error

(Not that I would write code like this normally ;-)

Is anything being done in VS2005 and C++/CLI to conform properties to
this natural C++ programming behaviour? After all, AFAICT what is
required is more compiler smarts - not any changes to C++ or CLI themselves.

Cheers,

Peter

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
G

Gary Chang

Hi Peter,

Currently I am consulting the product team with your issue, we will reply
here with more information as soon as possible.
If you have any more concerns on it, please feel free to post here.


Thanks for your understanding!

Best regards,

Gary Chang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
 
P

Peter Bromley

Please reread my post. I was not asking for the signature of the set_
members to be changed.

What I was noting was that the compiler does not allow a = B = 10 for
apparently no good reason.

Take a look at the il generated for B += 10. This compile to get_
followed by set_ . The complier could easily generate code for chained
assignment as set_ followed by get_ .

Hoping this clarifies my original query.

Peter
Hi Peter,
I followed up on your question and this is the response I got.

"It’s unlikely. The CLS requires the return type of the setter to be void. Allowing set to return a type other than void would be a C++ specific extension. That would result in some properties to allow assignment chaining, and other wouldn’t allow it. Overall, it doesn’t seem like that important of a feature to go down that path."


Basically it means that if C++ allows it, all languages would have to support it.
Thanks.


:

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
R

Ronald Laeremans [MSFT]

Get (nor set ) methods are guaranteed to be side-effect free. Unless the
setter returned the value directly that means the code would incur a side
effect where the C++ developer (and the C++ standard) do not expect or allow
that.

Ronald Laeremans
Visual C++ team
 
P

Peter Bromley

Ronald said:
Get (nor set ) methods are guaranteed to be side-effect free. Unless the
setter returned the value directly that means the code would incur a side
effect where the C++ developer (and the C++ standard) do not expect or allow
that.
Hi, Ronald, I accept what you are saying here and am not asking that
the signatures or behaviour of getters and setters be changed in any way

What I am trying to point out is that the compiler is (deliberately) not
generating code which would support chained assignment.

Look, in ummanaged C++ without properties I can do the following.

struct X {
int a;
}

main () {
X x;
int b = x.a = 20;
}

But if X is declared as

__value struct X {
__property int get_A(void) { return a; }
__property void set_A(int value) { a = value; }
private:
int a;
}

main () {
X x;
int b = x.A = 20; // ***
}

I get a compile time error on the line marked with ***.

Now what I am suggesting is that the error is unneccesary because this
code could be compiled to the equivalent of:

x.A = 20;
int b = x.A;

This sort of action is already supported for assignment operators like
+=, as you can see from the IL generated when I code

x.A += 5;

-->

ldloca.s x
ldloca.s x
call instance int32 Namespace.X::get_A()
ldc.i4.5
add
call instance void Namespace.X::set_A(int32)

So for

int b = x.A = 20

the compiler could generate something like

ldloca.s x
ldc.i4.s 20
call instance void Namespace.X::set_A(int32)
ldloca.s x
call instance int32 Namespace.X::get_A()
stloc.1


To recap, I am not suggesting that properties be changed in any way,
what I am suggesting is that the C++ compiler could make better use of
the property getter to support chained assignment operators.

Does this clarify my OP?

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
R

Ronald Laeremans [MSFT]

I think your IL illustrates perfectly what I was trying to illustrate. Hope
I can be a bit more concrete:

x += a;

Is for all most developers semantically equivalent to x = x + a;

or if X is implemented as a property:

set_X ( get_X() + a);

But x = y = a;

Is in standard C++ thinking (at least in our opinion) thougt of as:

set_Y (a);

DO !!NOT!! call get_Y which may have side effects, but use the return value
from set_Y (assignment operators in standard C++ return the assigned to
object) and the do

set_X(using return value of set_Y)

I hope that clarifies our thinking.

Ronald
 
P

Peter Bromley

Ronald said:
I think your IL illustrates perfectly what I was trying to illustrate. Hope
I can be a bit more concrete:

x += a;

Is for all most developers semantically equivalent to x = x + a;

or if X is implemented as a property:

set_X ( get_X() + a);

But x = y = a;

Is in standard C++ thinking (at least in our opinion) thougt of as:

set_Y (a);

DO !!NOT!! call get_Y which may have side effects, but use the return value
from set_Y (assignment operators in standard C++ return the assigned to
object) and the do

set_X(using return value of set_Y)
Hmmm, now I see what you are saying.

And you can't fix this dilemma without making setters return the set value.

Of course, 99% of property getters are simple side-effect free functions
which is where my OP came from. What a pity the CLS doesn't allow me to
specify a member function as const. (insert irony here).

Now I see you missed a "not" in this sentence ("not guaranteed"). Kinda
obscured your point there for a post or two.


--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
R

Ronald Laeremans [MSFT]

Yes, sorry about the missing "not". It did completely mask what I was trying
to explain.

Ronald
 

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

Top