C++ Evalue Assignment Operator In Perl

Because the "result" of an assignment is the value assigned... so it's still a expression in the second case. expressions require the condition to be a expression, which is satisfied by the second but not the first. Effectively, your two snippets are:

and

Is it clear from that expansion that the second version will compile but not the first?

This is one reason not to do comparisons with true and false directly. So I would always just write instead of and instead of . You still get into problems with ) when and are variables, admittedly - a typo there can cause an issue. I can't say it's ever happened to me though.

EDIT: Responding to your edit - assignments of all kinds can be used in statements - and loops etc, so long as the overall condition expression is . For example, you might have:

While I usually avoid side-effects in conditions, this particular idiom is often useful for the example shown above, or using . Basically it's "while the value I read is useful, use it."

UPDATE: I interrupt this episode of FAIC with a request from my friend and colleague Lucian, from the VB team, who wonders whether it is common in C# to take advantage of the fact that assignment expressions are expressions. The most common usage of this pattern is the subject of this blog entry: the fact that "chained" assignment works at all is a consequence of the fact that assignments are expressions, not statements. There are other uses too; one could imagine something like "return this.myField = x;" as a short cut for "this.myField = x; return this.myField;" -- perhaps we are performing some computation and then recording the results for use later. Or perhaps we've got something like myNonNullableString = (myNullableString = Foo()) ?? "<null>"; -- there are any number of ways this idiom could be used.

I do not use this idiom myself; I'm of the opinion that side effects such as assignments are best represented by putting each in a statement of its own, rather than as something embedded in a larger expression. My question for you is: do you use assignments as expressions? If so, how and why? Note that I am looking for mundane, "real world" examples of this pattern, not clever ideas about how this could in theory be used. If you've got one, please leave it in the comments and I'll pass it along to Lucian. Thanks!

*********************

Today I examine another myth about C#. Consider the following code:

a = b = c;

This is legal; you can make arbitrarily long chains of simple assignments. This pattern is most often seen in something like

int i, j, k;
i = j = k = 123;

I often hear that this works “because assignment is right-associative and results in the value of the right-hand side”.

Well, that’s half true. It is right-associative; obviously this has to be equivalent to

i = (j = (k = 123)));

It doesn’t make any sense to parenthesize it from the left. Now, in this particular example, the statement is true, but in general it is not. The result of the simple assignment operator is not the value of the right hand side:

const int x = 10;
short y;
object z;
z = y = x;
System.Console.WriteLine(z.GetType().ToString());

This prints “System.Int16”, not “System.Int32”. The value of the right-hand side of “y = x” is clearly an int, but we do not assign a reference to a boxed int to z, we assign a reference to a boxed short!

So then is the correct statement “… results in the value of the left-hand side”?

Nope, that’s not right either, and we can prove it.

class C
{
  private string x;
  public string X {
    get { return x ?? ""; }
    set { x = value; } }
  static void Main()
  {
    C c = new C();
    object z;
    z = c.X = null;
    System.Console.WriteLine(z == null);
    System.Console.WriteLine(c.X == null);
  }
}

This prints “True / False” – the result of the assignment operator is not the value of the left-hand-side. The value of the left hand side is the empty string but the value of the operator is null.

Heck, the left hand side need not even have a value. Write-only properties are weird and rare, but legal; if there were no getter then the left hand side c.X would not have a value!

The correct statement should now be pretty easy to deduce: the result of the simple assignment operator is the value that was assigned to the left-hand side.

 

0 comments

Leave a Reply

Your email address will not be published. Required fields are marked *