Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. dotNET Rant [modified]

dotNET Rant [modified]

Scheduled Pinned Locked Moved The Lounge
questioncsharpcomlearning
101 Posts 25 Posters 16 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T TheGreatAndPowerfulOz

    Pete Appleton wrote:

    void* one = 0; void* two = 0; BOOL same = (one == two); // false - the lvalues of one and two are different

    wrong, same would have a value of true. one and two would be null pointers.

    Pete Appleton wrote:

    BOOL sameValue = (*one == *two); // true - the rvalues are the same

    this would crash with a null pointer dereference error.

    Pete Appleton wrote:

    *one = 1; *two = 2; same = (one == two); // false - the lvalues are different

    correct

    Pete Appleton wrote:

    sameValue = (*one == *two); // false - the rvalues are different now

    this would crash with a illegal memory reference error

    Pete Appleton wrote:

    There's a reason why C# is called a C-based language... you may wish to brush up on your knowledge of pointers...

    perhaps you should.

    Fight Big Government:
    http://obamacareclassaction.com/
    http://obamacaretruth.org/

    P Offline
    P Offline
    Pete Appleton
    wrote on last edited by
    #79

    Do apologise - I missed the dereference void *one = &0; void *two = &0; Good thing I haven't used C for years :)

    -- What's a signature?

    1 Reply Last reply
    0
    • L Lost User

      Ok well if you would make == and Equals the same, either you would have to violate the "NaN == NaN is false" rule by saying that both == and Equals return true for two NaN's (potentially messing up peoples floating point maths, causing extra conversion problems between C# and other languages and reducing performance for floating point equality comparisons), or you would cause mayhem by allowing a case where a.Equals(a) is false (namely in the case that a is NaN) which causes unexpected results such as being unable to remove a NaN from a collection except by index (but you can't really get that index, either, except with some custom code that checks whether any element is unequal to itself) That "mayhem" can be "solved" by not using Equals like that. But then Equals has become essentially useless, since you can never count on its result having the same meaning - who knows maybe someone will throw in a NaN (maybe even on accident) and break your code.

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #80

      I think your example would be a corner case for floats and doubles if my way were to be adopted as I would still want to honor the IEEE meaning for NaN comparisons. However, I'm not a purist so much as a practical person. Anyway, this "argument" is moot, things are what they are, and I think we understand each other. And things certainly aren't going to change just cause *I* want them to. I was just having a temporary "brain fart". It just seems wrong that == and .Equals operate differently.

      Fight Big Government:
      http://obamacareclassaction.com/
      http://obamacaretruth.org/

      modified on Monday, May 10, 2010 12:50 PM

      1 Reply Last reply
      0
      • P PIEBALDconsult

        Nooo... that's correct. Otherwise, what would you do with this:

        int one = 0 ;
        int two = 0 ;

        bool same = (object) one == (object) two ;

        Shouldn't this perform the same reference comparison of your code? (Man, you miss one closing quote... :-O )

        modified on Thursday, May 6, 2010 7:38 PM

        T Offline
        T Offline
        TheGreatAndPowerfulOz
        wrote on last edited by
        #81

        Well, it seems that it would given my remembered(and corrected/reminded) understanding. So 'same' would be false. (Haven't typed it into a compiler yet so I don't really 'know' -- lol). In any case, my rant was incorrectly focused. I was really venting about a larger issue and focused on this one small thing. Still, looking at it from a novice perspective (which I'm not -- even though it sure sounded like it yesterday --, but it helps sometimes to do that), it seems incongruous to have the result it does. Of course, once explained to said novice, it's understood. It's just programming after all, and each language/runtime has its 'quirks'. cheers.

        Fight Big Government:
        http://obamacareclassaction.com/
        http://obamacaretruth.org/

        B 1 Reply Last reply
        0
        • S Scott Dorman

          If you had value types to start with, you are correct. Here is the difference...

          int iOne = 1;
          int iTwo = 2;

          object one = iOne;
          object two = iTwo;

          In this case, you have created two value types (iOne and iTwo, which you then assign to object variables. At the point of the assignment, the runtime is boxing the value types to reference types. However, in your case you have

          object one = 1;
          object two = 2;

          Which is not the same. Here you are assigning the literal values to the object variables, which don't create any value types.

          Scott Dorman

          Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


          Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

          T Offline
          T Offline
          TheGreatAndPowerfulOz
          wrote on last edited by
          #82

          That's an interesting oddity, to be sure. I don't see why the second case is not boxing. Isn't any literal integer a value type by definition? So then, if the two examples are different, then what is boxed in the first case? A reference to the iOne, iTwo variables? Or are their respective values boxed? And then what is the second case called, if not boxed? Consider the following code.

          void func(out object one, out object two)
          {
          int iOne = 1;
          one = iOne;

          two = 2;
          

          }

          what is in 'one' and what is in 'two' after the return of this function? I submit they're both boxed. Of course, I admit I'm no expert and I'm fully ready to be instructed.

          Fight Big Government:
          http://obamacareclassaction.com/
          http://obamacaretruth.org/

          B S 2 Replies Last reply
          0
          • T TheGreatAndPowerfulOz

            The one vote wasn't me. Look, whether I use == or .Equals should be semantically the same. so, leaving null values out of the picture, the result of a == b should be the same as calling a.Equals(b). if not, then something or other is fracked.

            Fight Big Government:
            http://obamacareclassaction.com/
            http://obamacaretruth.org/

            S Offline
            S Offline
            Sam Meacham
            wrote on last edited by
            #83

            What makes you think that a == b and a.Equals(b) should be the same? They are by definition different, and specifically used to check different things, both of which are necessary. Reference equals (the == operator, or the more explicit Object.ReferenceEquals method) checks to see if two variables (or pointers, since you are dealing with reference types) point to the same object in memory, e.g., do they have the same address. Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects. This is very well defined behavior, and most programming languages discern the difference between reference and value comparison. Just because you have not understood the problem, or better yet, the solution to the problem, does not mean that it is a design flaw. To assert that it is a design flaw it to also assert that you have a complete understanding of the language and the specification, and clearly, you do not.

            T T 2 Replies Last reply
            0
            • T TheGreatAndPowerfulOz

              ok, an MSIL lawyer! perhaps, it got optimized away. In any case, the result is false.

              Fight Big Government:
              http://obamacareclassaction.com/
              http://obamacaretruth.org/

              B Offline
              B Offline
              Brady Kelly
              wrote on last edited by
              #84

              Ooh, a promising more short term and immediate lawyer prospect for me, until I get my law degree. And it'll help with my work. :)

              1 Reply Last reply
              0
              • L Luc Pattyn

                To complicate matters: you do know some of those strings will be interned, and some won't. Now this thread is more technical than any of today's threads in the C# forum. It is time you realize this still is The Lounge. :)

                Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


                Prolific encyclopedia fixture proof-reader browser patron addict?
                We all depend on the beast below.


                B Offline
                B Offline
                Brady Kelly
                wrote on last edited by
                #85

                This far and no programming question per se, this is looking promising.

                1 Reply Last reply
                0
                • S Scott Dorman

                  If you had value types to start with, you are correct. Here is the difference...

                  int iOne = 1;
                  int iTwo = 2;

                  object one = iOne;
                  object two = iTwo;

                  In this case, you have created two value types (iOne and iTwo, which you then assign to object variables. At the point of the assignment, the runtime is boxing the value types to reference types. However, in your case you have

                  object one = 1;
                  object two = 2;

                  Which is not the same. Here you are assigning the literal values to the object variables, which don't create any value types.

                  Scott Dorman

                  Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                  Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                  B Offline
                  B Offline
                  Brady Kelly
                  wrote on last edited by
                  #86

                  Oh! :omg: Thanks Scott.

                  1 Reply Last reply
                  0
                  • T TheGreatAndPowerfulOz

                    That's an interesting oddity, to be sure. I don't see why the second case is not boxing. Isn't any literal integer a value type by definition? So then, if the two examples are different, then what is boxed in the first case? A reference to the iOne, iTwo variables? Or are their respective values boxed? And then what is the second case called, if not boxed? Consider the following code.

                    void func(out object one, out object two)
                    {
                    int iOne = 1;
                    one = iOne;

                    two = 2;
                    

                    }

                    what is in 'one' and what is in 'two' after the return of this function? I submit they're both boxed. Of course, I admit I'm no expert and I'm fully ready to be instructed.

                    Fight Big Government:
                    http://obamacareclassaction.com/
                    http://obamacaretruth.org/

                    B Offline
                    B Offline
                    Brady Kelly
                    wrote on last edited by
                    #87

                    In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

                    S T 2 Replies Last reply
                    0
                    • T TheGreatAndPowerfulOz

                      but in code that is comparing boxed values, you don't know what the boxed types are so it's not as simple as casting to a known type.

                      Fight Big Government:
                      http://obamacareclassaction.com/
                      http://obamacaretruth.org/

                      B Offline
                      B Offline
                      Brady Kelly
                      wrote on last edited by
                      #88

                      ahmed zahmed wrote:

                      you don't know what the boxed types

                      I think that is a key point, and maybe why '==' doesn't attempt a value comparison.

                      1 Reply Last reply
                      0
                      • T TheGreatAndPowerfulOz

                        Well, it seems that it would given my remembered(and corrected/reminded) understanding. So 'same' would be false. (Haven't typed it into a compiler yet so I don't really 'know' -- lol). In any case, my rant was incorrectly focused. I was really venting about a larger issue and focused on this one small thing. Still, looking at it from a novice perspective (which I'm not -- even though it sure sounded like it yesterday --, but it helps sometimes to do that), it seems incongruous to have the result it does. Of course, once explained to said novice, it's understood. It's just programming after all, and each language/runtime has its 'quirks'. cheers.

                        Fight Big Government:
                        http://obamacareclassaction.com/
                        http://obamacaretruth.org/

                        B Offline
                        B Offline
                        Brady Kelly
                        wrote on last edited by
                        #89

                        ahmed zahmed wrote:

                        Still, looking at it from a novice perspective (which I'm not -- even though it sure sounded like it yesterday --, but it helps sometimes to do that), it seems incongruous to have the result it does.

                        I suspect the same of the C# interpretation of the Laws for the pre- and post-decrement operators. I'll remember and post the experiment a bit later.

                        1 Reply Last reply
                        0
                        • T Tim Yen

                          I dont think there is a reason, just a coin toss. Because everything inherits from object it might be easier to compare the pointer values. But they could just as easily have done a ToString() on each object and compared values. Maybe its to deal with null references, where ToString() would not work? But then they could always have had some pre defined rule as when two null references are compared they are equal, like if both null then they are equal otherwise false

                          B Offline
                          B Offline
                          Brady Kelly
                          wrote on last edited by
                          #90

                          Tim Yen wrote:

                          Maybe its to deal with null references, where ToString() would not work?

                          Aha! My morning is complete, and the nagging question of why they don't just call Equals() on both objects is answered.

                          1 Reply Last reply
                          0
                          • D Daniel Grunwald

                            Because keeping all 2^32 possible integers around until they are (maybe) reused would waste up to 48 GB of RAM (or 96 GB on 64-bit systems, as the overhead of objects is higher there). And I don't really want the Java behavior where all integers between -128 and 127 return the same object, but all other integers don't.

                            C Offline
                            C Offline
                            CurtainDog
                            wrote on last edited by
                            #91

                            Fair call, I must admit I was mostly thinking of literals when I made my comment. These of course would be able to be handled at compile time.

                            1 Reply Last reply
                            0
                            • E englebart

                              This is because dotNET is Microsoft's version of Java, and that is how Java would do it. My guess is that you are coming from a C++ background where you expect it to call operator==(). The main difference between Java and the first dotNET was that Java lowercased the first letter of methods, while dotNET uppercased the first letter. dotNET has evolved at a much faster (almost unstable) pace since then. Disclosure: I am a Java programmer that is glad that MS created dotNET. Java would probably still not have enums if MS hadn't ditched Java and started competing directly against it.

                              C Offline
                              C Offline
                              CurtainDog
                              wrote on last edited by
                              #92

                              .Net is the platform and C# is the language; in the Javaverse they're both called Java, which is highly confusing. As pointed out in one of the responses above the original code would behave differently in Java because Java caches Integer 0. I'm also a Java programmer and with the exception of generics I'm ambivalent about the language changes in 1.5 & 1.6

                              1 Reply Last reply
                              0
                              • T TheGreatAndPowerfulOz

                                I dont think he was complaining about the 'ref' keyword, but rather the way == is overloaded on object to mean "compare" pointers. But, then when all you have is an 'object' what else can you do? Still it seems that the runtime knows that it's a boxed value-type and could do something 'smarter'. But I don't know the full implications of doing something like that, at least not now. Who knows what would break.

                                Fight Big Government:
                                http://obamacareclassaction.com/
                                http://obamacaretruth.org/

                                T Offline
                                T Offline
                                Tim Yen
                                wrote on last edited by
                                #93

                                Yes I wasn't saying the ref keyword didn't serve some purpose in the language as it is now, I was really leading to the fact that the designers of C# invented the ref keyword to deal with a particular problem and therefore they could have invented another way of making the == operator unambiguous. I imagine they could have invented a complex set of rules to avoid the keyword ref and potentially made the language more ambiguous which is what they have done with ==. Or they could have gone down the path of avoiding the overload. I think the language features are now cast in stone and it will take the next version of C# (maybe C##) to fix the silly bits.

                                1 Reply Last reply
                                0
                                • S Sam Meacham

                                  What makes you think that a == b and a.Equals(b) should be the same? They are by definition different, and specifically used to check different things, both of which are necessary. Reference equals (the == operator, or the more explicit Object.ReferenceEquals method) checks to see if two variables (or pointers, since you are dealing with reference types) point to the same object in memory, e.g., do they have the same address. Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects. This is very well defined behavior, and most programming languages discern the difference between reference and value comparison. Just because you have not understood the problem, or better yet, the solution to the problem, does not mean that it is a design flaw. To assert that it is a design flaw it to also assert that you have a complete understanding of the language and the specification, and clearly, you do not.

                                  T Offline
                                  T Offline
                                  Tim Yen
                                  wrote on last edited by
                                  #94

                                  hang on

                                  Sam Meacham wrote:

                                  Using a.Equals(b) is the same as Object.Equals(a, b), and it compares the values of the two objects.

                                  No it doesn't. http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx[^] "The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types" I don't think he has misunderstood the problem, I think you have misunderstood the original rant. The original rant is about they way equals works and him disagreeing with the way it works. He believes == should always do a value comparison and there should be some other way like ReferenceEquals() to do a reference comparison. I agree with him. The way == works now you have to know the type of the variables and then apply the rules. But the rules even then aren't 100% consistent, in the strange case of the string object == does a value comparison but all other objects it does a reference comparison. With the addition of the var keyword this type knowledge may not be available within the current function and possibly the current class or even current project. It may only be available in a referenced library. So you may not have access to the code and as such the type information until run time to do an == on a variable. After thinking about this for a while I think the reason they went down the current path is value comparison of two objects would require evaluating all branches of the object, which may be computationally expensive and potentially very expensive if your comparing say a list of lists of lists of objects. Still there could be other ways around this by generating compiler errors on "object == object" and developing other syntax like object.ReferenceEquals(object)

                                  1 Reply Last reply
                                  0
                                  • B Brady Kelly

                                    In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

                                    S Offline
                                    S Offline
                                    Scott Dorman
                                    wrote on last edited by
                                    #95

                                    Yes, that's pretty much correct.

                                    Scott Dorman

                                    Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                                    Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                                    1 Reply Last reply
                                    0
                                    • T TheGreatAndPowerfulOz

                                      That's an interesting oddity, to be sure. I don't see why the second case is not boxing. Isn't any literal integer a value type by definition? So then, if the two examples are different, then what is boxed in the first case? A reference to the iOne, iTwo variables? Or are their respective values boxed? And then what is the second case called, if not boxed? Consider the following code.

                                      void func(out object one, out object two)
                                      {
                                      int iOne = 1;
                                      one = iOne;

                                      two = 2;
                                      

                                      }

                                      what is in 'one' and what is in 'two' after the return of this function? I submit they're both boxed. Of course, I admit I'm no expert and I'm fully ready to be instructed.

                                      Fight Big Government:
                                      http://obamacareclassaction.com/
                                      http://obamacaretruth.org/

                                      S Offline
                                      S Offline
                                      Scott Dorman
                                      wrote on last edited by
                                      #96

                                      The second case is not boxing because you are assigning a literal value to the object. A literal value essentially takes on the type of the object to which it is assigned (not the real implementation details, but it should get the idea across). That would mean that a literal integer value is only a value type if it is assigned to a value type. In the second example, the literal values are assigned to object variables, so no boxing occurs. Any time a boxing operation occurs, the value of the value type being boxed is copied into the reference type. As for what the second case is called, there isn't a name since there is no boxing or unboxing operations. It is simply variable assignment. In your func example, you have a function with two out object parameters. In the body of the function, you are essentially doing two things:

                                      1. You create an int value type and then assign it to an object argument. This is a boxing operation.
                                      2. You assign a literal value 2 to an object argument. Since you are assigning a literal value, this is not a boxing operation.

                                      Scott Dorman

                                      Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                                      Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                                      T 1 Reply Last reply
                                      0
                                      • S Scott Dorman

                                        The second case is not boxing because you are assigning a literal value to the object. A literal value essentially takes on the type of the object to which it is assigned (not the real implementation details, but it should get the idea across). That would mean that a literal integer value is only a value type if it is assigned to a value type. In the second example, the literal values are assigned to object variables, so no boxing occurs. Any time a boxing operation occurs, the value of the value type being boxed is copied into the reference type. As for what the second case is called, there isn't a name since there is no boxing or unboxing operations. It is simply variable assignment. In your func example, you have a function with two out object parameters. In the body of the function, you are essentially doing two things:

                                        1. You create an int value type and then assign it to an object argument. This is a boxing operation.
                                        2. You assign a literal value 2 to an object argument. Since you are assigning a literal value, this is not a boxing operation.

                                        Scott Dorman

                                        Microsoft® MVP - Visual C# | MCPD President - Tampa Bay IASA [Blog][Articles][Forum Guidelines]


                                        Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai

                                        T Offline
                                        T Offline
                                        TheGreatAndPowerfulOz
                                        wrote on last edited by
                                        #97

                                        Thanks, Scott. That's very enlightening. Now I understand. Don't know why there should be a distinction in these cases, but what you're saying makes sense.

                                        Fight Big Government:
                                        http://obamacareclassaction.com/
                                        http://obamacaretruth.org/

                                        1 Reply Last reply
                                        0
                                        • B Brady Kelly

                                          In Scott's first case, a new Int32 object is created with a value. Assigning this object to another object causes boxing, because the RHS value type is not 'compatible' with the LHS ref type. In his second case, object one = 1;, once again a new Int32 object is created, but I assume that because it was created 'right there', buy the CLR, it can be directly assigned to the RHS. How far off the mark am I guys?

                                          T Offline
                                          T Offline
                                          TheGreatAndPowerfulOz
                                          wrote on last edited by
                                          #98

                                          Thanks Brady, yours and Scott's explanation helped a lot.

                                          Fight Big Government:
                                          http://obamacareclassaction.com/
                                          http://obamacaretruth.org/

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups