'null' references

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jon Skeet [C# MVP]

    #16
    Re: 'null' references

    Ben Voigt [C++ MVP] <rbv@nospam.nos pamwrote:
    Please, show me where a ref-by-ref is needed in C#/.NET
    >
    Immutable reference types, like string. Copy-on-write. Various times you
    need ReferenceEquals , not simply a clone, but the return value is already
    used.
    While I can think of some reasons why pass-by-ref of reference types is
    sometimes useful, I can't make head or tail of your reply,
    unfortunately. However, I suspect I could learn something if you'd be
    willing to elaborate.

    --
    Jon Skeet - <skeet@pobox.co m>
    http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
    If replying to the group, please do not mail me too

    Comment

    • Andy Bates

      #17
      Re: 'null' references

      Haven't read the whole thread but in C++... a pointer is used when the
      object may/can not exist; otherwise a reference is used when the object must
      exist.

      You can force a NULL reference to be used in C++ but it's definately not a
      practice that I'd recommend.

      If you are using a pointer then the check for NULL is imperative where as a
      reference must be bound to an object.

      - Andy

      "Ben Voigt [C++ MVP]" <rbv@nospam.nos pamwrote in message
      news:97896823-3D28-4BC6-B690-D9FF0721DF68@mi crosoft.com...
      >
      >>You can't use a null for a reference parameter in C++ either. The
      >>following generates a compile error, just as the "ref" parameter example
      >>you gave for C# does:
      >
      Yes you can. You do have to pass the correct type, however.
      >
      void Func(int &i)
      {
      }
      >
      void Caller()
      {
      Func(*(int*)nul lptr);
      }
      >
      It's a very bad idea, true, but people who use references instead of
      pointers simply because "I would have to check for NULL pointers, and
      references can't be NULL" are simply misinformed.

      Comment

      • Ben Voigt [C++ MVP]

        #18
        Re: 'null' references


        "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
        news:MPG.20dd11 d6ca25ab7723a@m snews.microsoft .com...
        Ben Voigt [C++ MVP] <rbv@nospam.nos pamwrote:
        Please, show me where a ref-by-ref is needed in C#/.NET
        >>
        >Immutable reference types, like string. Copy-on-write. Various times
        >you
        >need ReferenceEquals , not simply a clone, but the return value is already
        >used.
        >
        While I can think of some reasons why pass-by-ref of reference types is
        sometimes useful, I can't make head or tail of your reply,
        unfortunately. However, I suspect I could learn something if you'd be
        willing to elaborate.
        The argument against pass ref class by-ref seems to be that you should
        modify the referenced class in place. That isn't possible for immutable
        types, like string. To return string data by reference, you can pass a
        string variable by-ref, (or use a StringBuilder).

        Copy-on-write: If you aren't allowed to modify the object in-place, but have
        to clone it in order to change it, then the caller's reference needs to be
        updated to the new copy. Again, ref-by-ref. strings are actually a subset
        of this case.

        If the resulting value has to compare equal by referential equality every
        time it is returned, then you need to set the caller's reference equal to
        your own. Again, ref-by-ref.
        >
        --
        Jon Skeet - <skeet@pobox.co m>
        http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
        If replying to the group, please do not mail me too

        Comment

        • Ben Voigt [C++ MVP]

          #19
          Re: 'null' references


          "Andy Bates" <andy@ussdev.co mwrote in message
          news:e8zAhJ5rHH A.2376@TK2MSFTN GP05.phx.gbl...
          Haven't read the whole thread but in C++... a pointer is used when the
          object may/can not exist; otherwise a reference is used when the object
          must exist.
          Again, a reference can be just as invalid as a pointer.
          >
          You can force a NULL reference to be used in C++ but it's definately not a
          practice that I'd recommend.
          >
          If you are using a pointer then the check for NULL is imperative where as
          a reference must be bound to an object.
          No, it isn't. You can make the contract such that "such and such argument
          must not be NULL", then you don't need to check it. And no, a reference
          doesn't need to be bound to an object. *p creates a reference for any
          pointer p. If the pointer was NULL, there is no object.

          Admittedly my example was contrived, that was to use as much of the previous
          poster's incorrect claim as possible.
          >
          - Andy
          >
          "Ben Voigt [C++ MVP]" <rbv@nospam.nos pamwrote in message
          news:97896823-3D28-4BC6-B690-D9FF0721DF68@mi crosoft.com...
          >>
          >>>You can't use a null for a reference parameter in C++ either. The
          >>>following generates a compile error, just as the "ref" parameter example
          >>>you gave for C# does:
          >>
          >Yes you can. You do have to pass the correct type, however.
          >>
          > void Func(int &i)
          > {
          > }
          >>
          > void Caller()
          > {
          > Func(*(int*)nul lptr);
          > }
          >>
          >It's a very bad idea, true, but people who use references instead of
          >pointers simply because "I would have to check for NULL pointers, and
          >references can't be NULL" are simply misinformed.
          >
          >

          Comment

          • Peter Duniho

            #20
            Re: 'null' references

            On Fri, 15 Jun 2007 14:04:26 -0700, Ben Voigt [C++ MVP]
            <rbv@nospam.nos pamwrote:
            It's a very bad idea, true, but people who use references instead of
            pointers simply because "I would have to check for NULL pointers, and
            references can't be NULL" are simply misinformed.
            It's true. In C++ you can use casting to get around practically any
            limitation intentionally put into the language.

            I don't see how that invalidates my point though. I have never written
            C++ code that checks something passed by reference for null references,
            nor have I ever had to maintain code written that way.

            I never suggested that the reason to use references was to avoid having to
            check for null pointers, but I do feel that is in fact an advantage (if
            the caller wants to explicitly get around that safe-guard, that's a bug in
            the caller akin to using Reflection in C# to get around a variety of
            safe-guards C# puts into place), and I bristle at your implication (if not
            outright accusation) that I am "misinforme d" just for thinking so.

            Pete

            Comment

            • Peter Duniho

              #21
              Re: 'null' references

              On Fri, 15 Jun 2007 13:02:41 -0700, valentin tihomirov
              <V_tihomirov@be st.eewrote:
              Despite you cannot pass the null as argument, which is ubequitous, the
              most
              frequent parameter in C.
              You _can_ pass null as an argument. You just can't pass null as an
              argument for a "ref" parameter.

              >Again, how is this difference from passing by reference in C++?
              >
              Where do I tell that C# references are different from C++ references? I
              was
              speaking about the difference between "pointers" and "references "!
              Since a "ref" parameter is essentially the same as C++'s "&" by-reference
              parameter, and since the "ref" parameter type (along with "out" which isa
              special case of "ref") is the only situation in which your complaint about
              not being able to pass null is true, _that_ is "where you tell that C#
              references are different from C++ references".

              You brought it up. I'm just pointing out the fallacy in your complaint.
              >>Using reference to the bogus null-object, which we leave unmodifed when
              >>assign a new value to the reference to return.
              >
              >I don't understand this statement. How can you leave something
              >unmodified
              >while at the same time assigning a new value?
              >
              Very easily.
              function (ref a) {
              if (a != null)
              a = new object();
              }
              >
              b = null;
              function(ref b);
              The above code does _not_ leave "b" unmodified when an new value is
              assigned. It does leave "b" unmodified in the example calling code, but
              that's only because the function also does not assign a new value.
              The null passed by reference is left unmodified ;-)
              The null passed by reference would be left unmodified in any case. It's
              only "b" that would be modified or not, as that's the variable passed by
              reference.
              The same effect would be
              reached by different 'nulls'
              NULL = new Object();
              func(ref r) {
              if (r != NULL)
              r = returnVal;
              }
              I have no idea what you expect that code to do. You can't assign an
              object reference ("new Object()") to "null". You haven't declared "NULL",
              so I don't know if you mean that to be the same as "null", or something
              entirely different.
              >However, I fail to see how this is really much of an advantage. In C#
              >you
              >would be required to create a dummy local that you would just ignore.In
              >C++ you have to have code in the function itself to check whether the
              >parameter is null. Either way, there's extra code, and in the C# case
              >it
              >eliminates the chance of a null-dereference run-time error (in C++, if
              >you
              >forget to check for the parameter being null, you can crash).
              >
              .. and the water is wet. But I did not address this issue!
              Which issue? I agree that you didn't specifically raise the question of
              checking for null values. However, that _is_ really the only practical
              difference between your apparent desire to pass something by a pointer to
              the variable versus the C# "ref" parameter type.

              In that respect, you certainly did by implication "address this issue".
              [QUOTE]
              Read it once
              again:
              It has
              two disadvantages though: 1) you must declare a bogus reference
              variable;
              So too you must in C++, if using "by-reference" parameter passing.
              and 2) initialize it before passing to the function, where you could
              just
              pass a 0 right away. Furthermore, it prevents you from using 'out'
              arguments.[end quote]
              What prevents you from using "out" arguments? The use of the "out"
              parameter type is in fact how you can avoid having to initialize the
              variable passed into the function.
              Who argues that we should assign null (optional) arguments if the null
              passed means "user does not want us to out anything"?
              What do you mean by "assign null arguments"? You can't assign anything to
              a null reference or pointer.
              >I don't really think you understand the issues you're talking about
              >anyway
              >
              Because you read and respond on the thing I do not address.
              The fact that you think my response isn't relevant to the thing you are
              talking about is in fact the very evidence that you don't understand the
              thing that you are talking about.

              Pete

              Comment

              • Larry Smith

                #22
                Re: 'null' references

                The fact that you think my response isn't relevant to the thing you are
                talking about is in fact the very evidence that you don't understand the
                thing that you are talking about.
                I haven't read the entire thread but the issue to me boils down to this. Why
                isn't the following allowed:

                void Func(out Whatever whatever)
                {
                if (whatever != null)
                {
                whatever = new Whatever();
                }
                }

                Func(null);


                Comment

                • Larry Smith

                  #23
                  Re: 'null' references

                  >>You can't use a null for a reference parameter in C++ either. The
                  >>following generates a compile error, just as the "ref" parameter example
                  >>you gave for C# does:
                  >
                  Yes you can. You do have to pass the correct type, however.
                  >
                  void Func(int &i)
                  {
                  }
                  >
                  void Caller()
                  {
                  Func(*(int*)nul lptr);
                  }
                  >
                  It's a very bad idea, true, but people who use references instead of
                  pointers simply because "I would have to check for NULL pointers, and
                  references can't be NULL" are simply misinformed.
                  Not only is it bad, it's undefined behaviour so it doesn't qualify as valid
                  C++. You can't legally dereference a null pointer nor is a null reference
                  legally possible.


                  Comment

                  • Austin Ehlers

                    #24
                    Re: 'null' references

                    On Fri, 15 Jun 2007 16:27:50 -0500, "Ben Voigt [C++ MVP]"
                    <rbv@nospam.nos pamwrote:
                    >
                    >"Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
                    >news:MPG.20dd1 1d6ca25ab7723a@ msnews.microsof t.com...
                    >Ben Voigt [C++ MVP] <rbv@nospam.nos pamwrote:
                    >Please, show me where a ref-by-ref is needed in C#/.NET
                    >>>
                    >>Immutable reference types, like string. Copy-on-write. Various times
                    >>you
                    >>need ReferenceEquals , not simply a clone, but the return value is already
                    >>used.
                    >>
                    >While I can think of some reasons why pass-by-ref of reference types is
                    >sometimes useful, I can't make head or tail of your reply,
                    >unfortunatel y. However, I suspect I could learn something if you'd be
                    >willing to elaborate.
                    >
                    >The argument against pass ref class by-ref seems to be that you should
                    >modify the referenced class in place. That isn't possible for immutable
                    >types, like string. To return string data by reference, you can pass a
                    >string variable by-ref, (or use a StringBuilder).
                    Why not just use the return value, like String does? If you have
                    multiple parameters that need to be changed, then it is usually bad
                    code, trying to do too much in one method, and should be refactored
                    into a better design.

                    Seeing a reference type passed by-ref in code, particularly from
                    someone new to C#/.NET, is like seeing a class with a finalizer: it's
                    occasionally right, but not often.

                    (I'm also ignoring things like Remoting, as that's outside normal
                    C#/.NET usage.)
                    >Copy-on-write: If you aren't allowed to modify the object in-place, but have
                    >to clone it in order to change it, then the caller's reference needs to be
                    >updated to the new copy. Again, ref-by-ref. strings are actually a subset
                    >of this case.
                    Same.
                    >If the resulting value has to compare equal by referential equality every
                    >time it is returned, then you need to set the caller's reference equal to
                    >your own. Again, ref-by-ref.
                    Sorry, I'm not following you here. Any example code?

                    Austin

                    Comment

                    • Peter Duniho

                      #25
                      Re: 'null' references

                      On Fri, 15 Jun 2007 15:17:36 -0700, Austin Ehlers
                      <austin.ehlers. spam.@gmail.com wrote:
                      Why not just use the return value, like String does? If you have
                      multiple parameters that need to be changed, then it is usually bad
                      code, trying to do too much in one method, and should be refactored
                      into a better design.
                      I agree that for immutable types, the best solution is usually to return a
                      new instance as the result from a method, rather than using a "ref"
                      parameter. However, consider situations like TryParse where you want to
                      return more than one value: the new instance and a result code of some
                      sort, for example. Are you suggesting that the TryParse pattern is
                      indicative of poor design?

                      It's true that these situations aren't very common. But I wouldn't go so
                      far as to say that one never needs to pass reference variables by
                      reference.
                      Seeing a reference type passed by-ref in code, particularly from
                      someone new to C#/.NET, is like seeing a class with a finalizer: it's
                      occasionally right, but not often.
                      "Occasional ly right" being the operative phrase, IMHO. You wrote "Please,
                      show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
                      reply simply as doing just that, showing you where it's needed.

                      Pete

                      Comment

                      • Peter Duniho

                        #26
                        Re: 'null' references

                        On Fri, 15 Jun 2007 15:10:57 -0700, Larry Smith <no_spam@_nospa m.com
                        wrote:
                        I haven't read the entire thread but the issue to me boils down to
                        this. Why
                        isn't the following allowed:
                        >
                        void Func(out Whatever whatever)
                        {
                        if (whatever != null)
                        {
                        whatever = new Whatever();
                        }
                        }
                        >
                        Func(null);
                        I think it does boil down to that, and I think the answer is the same as
                        the reason why you can't do this in C++:

                        void Func(Whatever &whatever)
                        {
                        if (whatever != null)
                        {
                        whatever = new Whatever();
                        }
                        }

                        Func(nullptr);

                        In other words, there's no practical different in this respect between
                        C++ and C#, in spite of what the OP claims.

                        Comment

                        • Larry Smith

                          #27
                          Re: 'null' references

                          In other words, there's no practical different in this respect between
                          C++ and C#, in spite of what the OP claims.
                          Apparently so but it didn't have to be that way. It may be a religious issue
                          but I would have voted to support it.


                          Comment

                          • Austin Ehlers

                            #28
                            Re: 'null' references

                            On Fri, 15 Jun 2007 15:39:24 -0700, "Peter Duniho"
                            <NpOeStPeAdM@nn owslpianmk.comw rote:
                            >On Fri, 15 Jun 2007 15:17:36 -0700, Austin Ehlers
                            ><austin.ehlers .spam.@gmail.co mwrote:
                            >
                            >Why not just use the return value, like String does? If you have
                            >multiple parameters that need to be changed, then it is usually bad
                            >code, trying to do too much in one method, and should be refactored
                            >into a better design.
                            >
                            >I agree that for immutable types, the best solution is usually to return a
                            >new instance as the result from a method, rather than using a "ref"
                            >parameter. However, consider situations like TryParse where you want to
                            >return more than one value: the new instance and a result code of some
                            >sort, for example. Are you suggesting that the TryParse pattern is
                            >indicative of poor design?
                            >
                            >It's true that these situations aren't very common. But I wouldn't go so
                            >far as to say that one never needs to pass reference variables by
                            >reference.
                            >
                            But is that a reference type? Besides IPAddress.TryPa rse, they're all
                            structs. (Notice I said "usually bad, trying to do too much in one
                            method". Parsing a string into a type is a common, single idea).
                            >Seeing a reference type passed by-ref in code, particularly from
                            >someone new to C#/.NET, is like seeing a class with a finalizer: it's
                            >occasionally right, but not often.
                            >
                            >"Occasionall y right" being the operative phrase, IMHO. You wrote "Please,
                            >show me where a ref-by-ref is needed in C#/.NET". I interpreted Ben's
                            >reply simply as doing just that, showing you where it's needed.
                            And that's fine. I'm just trying to show the OP that things are
                            different in C# than C/C++, and trying to use C-style code will lead
                            to a bad design.

                            Austin

                            Comment

                            • Jon Skeet [C# MVP]

                              #29
                              Re: 'null' references

                              Ben Voigt [C++ MVP] <rbv@nospam.nos pamwrote:
                              While I can think of some reasons why pass-by-ref of reference types is
                              sometimes useful, I can't make head or tail of your reply,
                              unfortunately. However, I suspect I could learn something if you'd be
                              willing to elaborate.
                              >
                              The argument against pass ref class by-ref seems to be that you should
                              modify the referenced class in place. That isn't possible for immutable
                              types, like string. To return string data by reference, you can pass a
                              string variable by-ref, (or use a StringBuilder).
                              Agreed.
                              Copy-on-write: If you aren't allowed to modify the object in-place, but have
                              to clone it in order to change it, then the caller's reference needs to be
                              updated to the new copy. Again, ref-by-ref. strings are actually a subset
                              of this case.
                              Right, I 'm with you.
                              If the resulting value has to compare equal by referential equality every
                              time it is returned, then you need to set the caller's reference equal to
                              your own. Again, ref-by-ref.
                              Hmm... that may be an idiom I've never come across. The first two make
                              absolute sense (even if they're fairly rarely required), but this one
                              is outside my experience.

                              --
                              Jon Skeet - <skeet@pobox.co m>
                              http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                              If replying to the group, please do not mail me too

                              Comment

                              • Jon Skeet [C# MVP]

                                #30
                                Re: 'null' references

                                Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:
                                Despite you cannot pass the null as argument, which is ubequitous, the
                                most frequent parameter in C.
                                >
                                You _can_ pass null as an argument. You just can't pass null as an
                                argument for a "ref" parameter.
                                And it's important to note that it's not to do with it being null -
                                it's to do with being a *value* rather than a *variable*. If you try to
                                use the result of a method call as a ref parameter you fail in the same
                                way - ditto if you use a string literal.

                                <snip>

                                --
                                Jon Skeet - <skeet@pobox.co m>
                                http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                                If replying to the group, please do not mail me too

                                Comment

                                Working...