Why does this code work?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Daniel Billingsley

    Why does this code work?

    Or seem to anyway.
    =====
    string abc;
    if ((abc=getString ()) != "")
    {
    MessageBox.Show (abc);
    }

    private string getString()
    {
    return "something" ;
    }
    =====
    I get the MessageBox displayed. If I change != to == there's no MessageBox.

    What is the != comparing, and how?


  • Adam Clauss

    #2
    Re: Why does this code work?

    "Daniel Billingsley" <dbillingsley@N O_durcon_SPAAMM .com> wrote in message news:uqONyxYcEH A.596@TK2MSFTNG P11.phx.gbl...[color=blue]
    > Or seem to anyway.
    > =====
    > string abc;
    > if ((abc=getString ()) != "")
    > {
    > MessageBox.Show (abc);
    > }[/color]

    As your parenthesis indicate, the first thing that happens is:
    (abc=getString( ))
    so, abc gets the value of "something"

    Which is then tested to be != to "", which is true. "something" != "" so the messagebox shows. Why do you feel there it should be
    otherwise?

    --
    Adam Clauss
    cabadam@tamu.ed u

    [color=blue]
    >
    > private string getString()
    > {
    > return "something" ;
    > }
    > =====
    > I get the MessageBox displayed. If I change != to == there's no MessageBox.
    >
    > What is the != comparing, and how?
    >
    >[/color]

    Comment

    • Shiva

      #3
      Re: Why does this code work?

      Hi,

      Since abc is assigned to the value returned by getString() and then that
      value is compared to "" (condition validates to true), MessageBox is shown.
      In case of ==, the condition validates to false and no messagebox.

      "Daniel Billingsley" <dbillingsley@N O_durcon_SPAAMM .com> wrote in message
      news:uqONyxYcEH A.596@TK2MSFTNG P11.phx.gbl...
      Or seem to anyway.
      =====
      string abc;
      if ((abc=getString ()) != "")
      {
      MessageBox.Show (abc);
      }

      private string getString()
      {
      return "something" ;
      }
      =====
      I get the MessageBox displayed. If I change != to == there's no MessageBox.

      What is the != comparing, and how?



      Comment

      • Jon Skeet [C# MVP]

        #4
        Re: Why does this code work?

        Daniel Billingsley <dbillingsley@N O_durcon_SPAAMM .com> wrote:[color=blue]
        > Or seem to anyway.
        > =====
        > string abc;
        > if ((abc=getString ()) != "")
        > {
        > MessageBox.Show (abc);
        > }
        >
        > private string getString()
        > {
        > return "something" ;
        > }
        > =====
        > I get the MessageBox displayed. If I change != to == there's no MessageBox.
        >
        > What is the != comparing, and how?[/color]

        It's comparing "" to the value of the expression (abc=getString( ))
        which is the value of abc after the assignment, which is "something" .
        It's the same way that the common:

        while ( (line=streamRea der.ReadLine()) != null)

        or

        while ( (read=stream.Re ad(buffer, 0, buffer.Length)) > 0)

        work.

        --
        Jon Skeet - <skeet@pobox.co m>
        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

        If replying to the group, please do not mail me too

        Comment

        • David Totzke (.NET/C# MVP)

          #5
          Re: Why does this code work?

          "Adam Clauss" <cabadam@tamu.e du> wrote in
          news:esV2o0YcEH A.1896@TK2MSFTN GP10.phx.gbl:
          [color=blue]
          > "Daniel Billingsley" <dbillingsley@N O_durcon_SPAAMM .com> wrote in
          > message news:uqONyxYcEH A.596@TK2MSFTNG P11.phx.gbl...[color=green]
          >> Or seem to anyway.
          >> =====
          >> string abc;
          >> if ((abc=getString ()) != "")
          >> {
          >> MessageBox.Show (abc);
          >> }[/color]
          >
          > As your parenthesis indicate, the first thing that happens is:
          > (abc=getString( ))
          > so, abc gets the value of "something"
          >
          > Which is then tested to be != to "", which is true. "something" != ""
          > so the messagebox shows. Why do you feel there it should be
          > otherwise?
          >[/color]

          Perhaps because the code reads:

          If you assign the return value of getString() to abc and compare that
          _operation_ to "" testing for inequality then...

          (abc = getString()) has no return value and fails by throwing an exception
          if something goes wrong; so, as the person asked, what is != comparing
          with?

          See my other reply for the answer.

          Dave

          Comment

          • David Totzke (.NET/C# MVP)

            #6
            Re: Why does this code work?

            "Daniel Billingsley" <dbillingsley@N O_durcon_SPAAMM .com> wrote in
            news:uqONyxYcEH A.596@TK2MSFTNG P11.phx.gbl:
            [color=blue]
            > Or seem to anyway.
            > =====
            > string abc;
            > if ((abc=getString ()) != "")
            > {
            > MessageBox.Show (abc);
            > }
            >
            > private string getString()
            > {
            > return "something" ;
            > }
            > =====
            > I get the MessageBox displayed. If I change != to == there's no
            > MessageBox.
            >
            > What is the != comparing, and how?
            >
            >[/color]

            Interesting question. Let's see what the compiler is up to by using ILDASM
            to look at the generated IL code. I've put the code in the click event of
            a button.


            ..method private hidebysig instance void button1_Click(o bject sender,
            class [mscorlib]
            System.EventArg s e) cil managed
            {
            // Code size 32 (0x20)
            .maxstack 2
            .locals init ([0] string abc)

            //push the this pointer onto the stack
            IL_0000: ldarg.0
            //Stack now looks like:
            // this


            //load the return value of getString onto the stack
            IL_0001: call instance string WindowsApplicat ion5.Form1::get String
            ()
            //Stack now looks like:
            // this, "Something"

            //Copy the top most value on the stack
            IL_0006: dup
            //Stack now looks like:
            // this, "Something" , "Something"

            //Store the topmost value on the stack to
            //the first local variable (abc in this case)
            IL_0007: stloc.0
            //Stack now looks like:
            // this, "Something"

            //Load an empty string onto the stack
            IL_0008: ldstr ""
            //Stack now looks like:
            // this, "Something" , ""

            //Test the top two values on the stack for
            //Inequality
            IL_000d: call bool [mscorlib]System.String:: op_Inequality
            string,string)
            //Stack now looks like:
            // this

            //If False then jump to IL_001f
            IL_0012: brfalse.s IL_001f

            //Since the comparison of the top two stack values
            //returns true you get the message box
            //Load the string onto the stack
            IL_0014: ldstr "Hello Something"
            //Stack now looks like:
            // this, "Hello Something"

            //Show the message box
            IL_0019: call valuetype [System.Windows. Forms]
            System.Windows. Forms.DialogRes ult [System.Windows. Forms]
            System.Windows. Forms.MessageBo x::Show(string)
            //Stack now looks like:
            // this

            //pop the this pointer off the stack
            IL_001e: pop

            //return
            IL_001f: ret
            } // end of method Form1::button1_ Click

            So, now you can see what is happening behind the scenes which should help
            to explain what was going on in that expression and why it works.

            Dave

            Comment

            • Adam Clauss

              #7
              Re: Why does this code work?

              > (abc = getString()) has no return value and fails by throwing an exception[color=blue]
              > if something goes wrong; so, as the person asked, what is != comparing
              > with?[/color]

              What do you mean it has no return value... it most certainly does. Returns the value of the string assigned. The assignment
              operator returns the value assigned (or reference, whatever you happen to be dealing with).
              It is what allows:
              string a = "a";
              string b, c;
              b = c = a;

              Also, the same principle as something like this would work:
              StreamReader sr = .....
              string line;
              while ( (line = sr.ReadLine()) != null)
              {
              ....
              }

              If the assignment operator did not return a value, neither of the above would be possible.

              --
              Adam Clauss
              cabadam@tamu.ed u

              Comment

              • David Totzke (.NET/C# MVP)

                #8
                Re: Why does this code work?

                "Adam Clauss" <cabadam@tamu.e du> wrote in
                news:#HifUPbcEH A.212@TK2MSFTNG P12.phx.gbl:
                [color=blue][color=green]
                >> (abc = getString()) has no return value and fails by throwing an
                >> exception if something goes wrong; so, as the person asked, what is
                >> != comparing with?[/color]
                >
                > What do you mean it has no return value... it most certainly does.
                > Returns the value of the string assigned. The assignment operator
                > returns the value assigned (or reference, whatever you happen to be
                > dealing with). It is what allows:
                > string a = "a";
                > string b, c;
                > b = c = a;
                >
                > Also, the same principle as something like this would work:
                > StreamReader sr = .....
                > string line;
                > while ( (line = sr.ReadLine()) != null)
                > {
                > ...
                > }
                >
                > If the assignment operator did not return a value, neither of the
                > above would be possible.
                >[/color]

                Not the *operator*. The actual operation that's in parens.

                (abc = getString()); is a stand alone operation. abc gets the value of
                getString() but the code does not read:

                abc = getString();
                if(abc != "")

                In the example, the left operand of the != operator is an expression.
                There's no extra "=" operator as in your example so that something like
                this would be obvious:

                (a = (b = c) != "")

                which is effectively the same as
                b = c;
                a = b;
                a != "";

                What we have is:

                b = c;
                ? != "";




                Comment

                • Adam Clauss

                  #9
                  Re: Why does this code work?

                  "David Totzke (.NET/C# MVP)" <david.totzke@g mail.com> wrote in message news:Xns9530A2D D21712davidtotz kegmailcom@207. 35.177.134...[color=blue]
                  > "Adam Clauss" <cabadam@tamu.e du> wrote in
                  > news:#HifUPbcEH A.212@TK2MSFTNG P12.phx.gbl:
                  > What we have is:
                  >
                  > b = c;
                  > ? != "";[/color]

                  Where in this case, by definition of the assignment operator ? IS abc.

                  --
                  Adam Clauss
                  cabadam@tamu.ed u

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: Why does this code work?

                    David Totzke (.NET/C# MVP) <david.totzke@g mail.com> wrote:[color=blue]
                    > Perhaps because the code reads:
                    >
                    > If you assign the return value of getString() to abc and compare that
                    > _operation_ to "" testing for inequality then...
                    >
                    > (abc = getString()) has no return value and fails by throwing an exception
                    > if something goes wrong; so, as the person asked, what is != comparing
                    > with?[/color]

                    No, the expression (abc=getString( )) *does* have a value (not a return
                    value, but a value).

                    From section 14.13.1 of the ECMA C# spec:

                    <quote>
                    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                    </quote>

                    That value is what != is comparing with.

                    --
                    Jon Skeet - <skeet@pobox.co m>
                    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                    If replying to the group, please do not mail me too

                    Comment

                    • Jon Skeet [C# MVP]

                      #11
                      Re: Why does this code work?

                      David Totzke (.NET/C# MVP) <david.totzke@g mail.com> wrote:[color=blue][color=green]
                      > > If the assignment operator did not return a value, neither of the
                      > > above would be possible.[/color]
                      >
                      > Not the *operator*. The actual operation that's in parens.
                      >
                      > (abc = getString()); is a stand alone operation. abc gets the value of
                      > getString() but the code does not read:
                      >
                      > abc = getString();
                      > if(abc != "")[/color]

                      Although it doesn't read that way, it is semantically equivalent to
                      that.
                      [color=blue]
                      > In the example, the left operand of the != operator is an expression.[/color]

                      Yes, and the value of the expression is the value assigned to the left-
                      hand side of the assignment operator, as specified in the C# language
                      specification.

                      --
                      Jon Skeet - <skeet@pobox.co m>
                      Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                      If replying to the group, please do not mail me too

                      Comment

                      • BMermuys

                        #12
                        Re: Why does this code work?

                        Hi,
                        inline

                        "David Totzke (.NET/C# MVP)" <david.totzke@g mail.com> wrote in message
                        news:Xns9530A2D D21712davidtotz kegmailcom@207. 35.177.134...[color=blue]
                        > "Adam Clauss" <cabadam@tamu.e du> wrote in
                        > news:#HifUPbcEH A.212@TK2MSFTNG P12.phx.gbl:
                        >[color=green][color=darkred]
                        > >> (abc = getString()) has no return value and fails by throwing an
                        > >> exception if something goes wrong; so, as the person asked, what is
                        > >> != comparing with?[/color]
                        > >
                        > > What do you mean it has no return value... it most certainly does.
                        > > Returns the value of the string assigned. The assignment operator
                        > > returns the value assigned (or reference, whatever you happen to be
                        > > dealing with). It is what allows:
                        > > string a = "a";
                        > > string b, c;
                        > > b = c = a;
                        > >
                        > > Also, the same principle as something like this would work:
                        > > StreamReader sr = .....
                        > > string line;
                        > > while ( (line = sr.ReadLine()) != null)
                        > > {
                        > > ...
                        > > }
                        > >
                        > > If the assignment operator did not return a value, neither of the
                        > > above would be possible.
                        > >[/color]
                        >
                        > Not the *operator*. The actual operation that's in parens.
                        >
                        > (abc = getString()); is a stand alone operation. abc gets the value of
                        > getString() but the code does not read:
                        >
                        > abc = getString();
                        > if(abc != "")
                        >
                        > In the example, the left operand of the != operator is an expression.
                        > There's no extra "=" operator as in your example so that something like
                        > this would be obvious:
                        >
                        > (a = (b = c) != "")
                        >
                        > which is effectively the same as
                        > b = c;
                        > a = b;
                        > a != "";[/color]

                        No, it's not.

                        (a = (b = c) != "") doesn't compile, and it's effectively the same as:

                        b = c;
                        a = (b!=""); // ERROR, assigning bool to string

                        [color=blue]
                        >
                        > What we have is:
                        >
                        > b = c;
                        > ? != "";[/color]

                        Wrong. (b=c) has the value of b after c is assigned to it.


                        Greetings

                        [color=blue]
                        >
                        >
                        >
                        >[/color]


                        Comment

                        • Daniel Billingsley

                          #13
                          Re: Why does this code work?

                          Thanks Jon, that's exactly what I was looking for.

                          "Jon Skeet [C# MVP]" <skeet@pobox.co m> wrote in message
                          news:MPG.1b6cf0 cd3bd9c7e598afa 3@msnews.micros oft.com...[color=blue]
                          >
                          > Yes, and the value of the expression is the value assigned to the left-
                          > hand side of the assignment operator, as specified in the C# language
                          > specification.
                          >
                          > --
                          > Jon Skeet - <skeet@pobox.co m>
                          > http://www.pobox.com/~skeet
                          > If replying to the group, please do not mail me too[/color]


                          Comment

                          • David Totzke (.NET/C# MVP)

                            #14
                            Re: Why does this code work?

                            Jon Skeet [C# MVP] <skeet@pobox.co m> wrote in
                            news:MPG.1b6cf0 cd3bd9c7e598afa 3@msnews.micros oft.com:
                            [color=blue]
                            > Yes, and the value of the expression is the value assigned to the left-
                            > hand side of the assignment operator, as specified in the C# language
                            > specification.
                            >[/color]

                            The original responses to the question were basically things like this:
                            "What did you expect?"

                            I took a shot and showed under the covers why it does work. Not being one
                            for reading specs the statement's functionality does seem counter
                            intuitive. The spec makes it plain. Your answer now is a good one and
                            I've learned something from the exercise.

                            Someone pointed out one of the flaws in my analysis in that
                            (a = (b = c) != "") doesn't compile because (b = c) evaluates to a bool and
                            we get the old implicit type conversion error. So my next question would
                            be:

                            Why does...oh CRAP! I just saw my mistake. It's trying to assign the
                            value of (b = c) != "" to a. A bool and a string.

                            I originally went astray because I know that at some point I have hosed
                            myself by using the assignment operator in an if condition instead of the
                            comparison and it was never false because the assignment always worked.
                            This if(b = c){} won't compile in C# but I know I did it somewhere. Nearly
                            went insane until I spotted it. C++ maybe? Can anybody tell me?

                            Thanks for the help.

                            Cheers,
                            Dave

                            Comment

                            • Jon Skeet [C# MVP]

                              #15
                              Re: Why does this code work?

                              David Totzke (.NET/C# MVP) <david.totzke@g mail.com> wrote:[color=blue]
                              > This if(b = c){} won't compile in C# but I know I did it somewhere. Nearly
                              > went insane until I spotted it. C++ maybe? Can anybody tell me?[/color]

                              Yes, that works in C/C++, which is why you often see people writing

                              if (5==x)

                              instead of

                              if (x==5)

                              in case you make a typo and turn it into an assignment instead of a
                              comparison. In C# this is not needed (unless you're comparing boolean
                              constants, and there I usually just write if(x) or if(!x)) and makes
                              the code less readable, IMO.

                              --
                              Jon Skeet - <skeet@pobox.co m>
                              Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                              If replying to the group, please do not mail me too

                              Comment

                              Working...