learn C++ or C#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Wilkinson

    Re: learn C++ or C#

    Peter Duniho wrote:
    >Not only is the "using" mechanism less convenient/elegant for the
    >client of the class than RAII (not to mention the possibility of
    >forgetting to do it), but a C# Dispose'd object can still be used
    >(unlike a C++ object that goes out of scope or is delete'd).
    >
    I was comprehending your post until "or is delete'd". There's nothing
    in C++ to stop someone from trying to use an object that's been deleted,
    and depending on how the memory was allocated and what the class does in
    its destructor, doing so might even work for awhile.
    >
    >This places an additional burden on the writer of an IDisposable class.
    >
    I don't see how it's any more burden than already exists in C++.
    There's no requirement that a disposable class actually catch
    post-disposal uses. It's nicer, but then so too would it be nicer for a
    C++ class to catch uses that occur after destruction. And I think it's
    easier for a C# class to do so, because the object is still actually
    allocated and the code in the class can behave predictably; in C++,
    sometimes using an object after destruction will fail immediately, and
    sometimes it won't.
    >
    >IMHO, any use of a Dispose'd object should automatically cause a
    >"ObjectIsDeadE xception" rather than relying on the author to test and
    >throw an ObjectDisposedE xception in every method.
    >
    I don't disagree that RAII allows for an object to simply "disappear"
    when the scope is exited, but this is how "using" works in C# too.
    Variables declared in the "using" statement are valid only for the scope
    of the block of that statement.
    >
    And just as in C#, the reference to the variable declared in the "using"
    statement could "escape" by being passed to something else, so too could
    a pointer to a stack-allocated C++ object escape. RAII in C++ doesn't
    actually guarantee that you can't use the object reference after the
    object itself has been destroyed. It just ensures that the object is
    destroyed outside a particular scope, just as "using" does.
    >
    If anything, at least with a garbage collecting system, you know that if
    you have a reference to something, that's a valid reference. The object
    itself might be in an unusable state, but it will always be able to tell
    you that one way or the other.
    <snip>

    Pete:

    Well, I think C++ programmers (even bad ones) are generally aware of lifetime
    issues, whereas C# programmers can be lulled into a sense of false security by
    the "garbage collector will take care of everything" mindset.

    I just find this notion of the "half dead" object rather disturbing. Surely it
    would have been possible for the C# language to be defined such that use of a
    Dispose'd object automatically throws an exception?

    --
    David Wilkinson
    Visual C++ MVP

    Comment

    • Peter Duniho

      Re: learn C++ or C#

      On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
      <andre.kaufmann _re_move_@t-online.dewrote:
      [...]
      When I remove (f) from list (a) I have to check if list (b) holds the
      file object too or rely on GC to close it - but I think that wouldn't be
      a good idea, since the file would be open, till the GC has disposed the
      object.
      >
      In C++ I can use RAII smart pointers to ensure that the file is closed
      as soon as it's not used anymore. In C# I have no automatism to handle
      this.
      But you can include reference counting in the C# object if you want. You
      can even implement a "smart pointer" class that uses Dispose() to
      decrement the counter and call Dispose() on the wrapped object if it
      reaches 0.

      Personally, I've had enough headaches with reference counting in my
      lifetime, and I try to avoid it when I can, smart pointers
      notwithstanding . I prefer to not create designs in the first place where
      unique ownership of the object is unclear. But there's nothing about C#
      that precludes using that technique if you find yourself in a situation
      where you think it's useful or needed.

      Pete

      Comment

      • Peter Duniho

        Re: learn C++ or C#

        On Thu, 24 Jul 2008 12:41:17 -0700, David Wilkinson
        <no-reply@effisols. comwrote:
        Well, I think C++ programmers (even bad ones) are generally aware of
        lifetime issues, whereas C# programmers can be lulled into a sense of
        false security by the "garbage collector will take care of everything"
        mindset.
        I have seen too much bad C++ code (especially code with rampant memory
        leaks) in my life to have the high opinion of bad C++ programmers you
        apparently have. Conversely, part of being proficient with C# is
        understanding how the garbage collection works, and how that interacts
        with the non-garbage-collecting parts of the platform. Only bad C#
        programmers are "lulled into a sense of false security".
        I just find this notion of the "half dead" object rather disturbing.
        Surely it would have been possible for the C# language to be defined
        such that use of a Dispose'd object automatically throws an exception?
        Well, first of all, to some extent it's a question of what the CLR
        requires, not what C# requires. And sure, it could. But why?
        IDisposable has a specific goal in mind, and no part of that goal involves
        requiring that an object become unusable after Dispose() is called.

        Inasmuch as there may be classes out there for which it makes sense to
        still be able to use the object after it's been disposed, why should the
        language or run-time impose an arbitrary restriction on that ability?

        As an example: the Form class does not dispose instances when the Form is
        closed if it was shown using ShowDialog(), even though it does if the Form
        was shown using Show(). This inconsistent behavior is to allow retrieval
        of values from the controls in the form after it's been closed. But one
        can easily imagine an implementation that completely separates the
        unmanaged aspects from the managed aspects, copying any data from the
        unmanaged resources upon disposal so that they are still accessible. Then
        closing the modal form could be the same as closing the non-modal form: in
        both cases, closing implies disposal.

        But one could only make that more consistent behavior as long as the
        run-time allows a disposed object to be used after Dispose() is called.

        Just because an object is done with its unmanaged resources, that doesn't
        mean to me that it's "half-dead". It's just done with the unmanaged
        resources. If a class wants to allow disposal prior to actually being
        done with the object and still permit certain operations on the object
        after disposal, that should be its right.

        Pete

        Comment

        • Jon Skeet [C# MVP]

          Re: learn C++ or C#

          Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:

          <snip>
          Just because an object is done with its unmanaged resources, that doesn't
          mean to me that it's "half-dead". It's just done with the unmanaged
          resources. If a class wants to allow disposal prior to actually being
          done with the object and still permit certain operations on the object
          after disposal, that should be its right.
          MemoryStream is one example, by the way - you can still call ToArray on
          it after closing it as a stream.

          --
          Jon Skeet - <skeet@pobox.co m>
          Web site: http://www.pobox.com/~skeet
          Blog: http://www.msmvps.com/jon.skeet
          C# in Depth: http://csharpindepth.com

          Comment

          • Ben Voigt [C++ MVP]

            Re: learn C++ or C#

            A simple example:
            >
            How do I ensure in C++ that I have successfully overridden a base
            class virtual function and that the compiler throws an error if the
            base class implementation has changed ?
            You can't do that in any language I'm aware of, so it's a non-issue. Did
            you mean "error if the signature of the function in the base class has
            changed"?
            >
            Andre

            Comment

            • Ben Voigt [C++ MVP]

              Re: learn C++ or C#

              Peter Duniho wrote:
              On Thu, 24 Jul 2008 10:25:47 -0700, Giovanni Dicanio
              <gdicanio@_nosp am_email_dot_it wrote:
              >
              >"Peter Duniho"
              >>
              >>In C++, RAII provides a convenient way to deal with that, and in
              >>C#, the "using" statement does the same. You may prefer one syntax
              >>over the other, but I personally don't see a difference between the
              >>two that would
              >>justify an argument of superiority one way or the other.
              >>
              >Destructor and "scope" syntax in C++ is cleaner, simpler and more
              >elegant than C# bloated 'using'.
              >
              Purely subjective. That sort of claim has no place in a technical
              discussion.
              It's quite objective. In C++, the burden is on the library developer, the
              user needs no extra syntax to benefit from automatic cleanup.
              >
              >Moreover, there is big difference between C++ RAII and C# "using".
              >>
              >In Andre's words:
              >>
              ><quote>
              >Using is fine if I hold a resource in a control block, but if the
              >resource is held by let's say multiple lists, I have to use some
              >kind of smart pointers to handle the resources efficiently.
              ></quote>
              >
              RAII doesn't _inherently_ support "smart pointers", nor does a garbage
              collecting system prevent one from implementing "smart pointers".
              >
              As I pointed out before, in a 100% GC-ed system, "smart pointers"
              become unnecessary anyway. But in a mixed system (i.e. pretty much
              Nothing could be further from the truth. Lazy (or deferred, if you prefer)
              cleanup breaks access to shared resources, and does so
              non-deterministical ly.
              any current platform), it's entirely possible to implement "smart
              pointers", and they can work in a very similar way to that
              implemented with RAII.
              No, in C# it's not possible to create an object that automatically performs
              cleanup when it becomes unreachable. You can only do so (1) manually, or
              (2) when its memory is reclaimed.
              >
              Which only brings us back to your purely subjective complaints about
              "using".
              >
              Pete

              Comment

              • Ben Voigt [C++ MVP]

                Re: learn C++ or C#

                Peter Duniho wrote:
                On Thu, 24 Jul 2008 10:35:59 -0700, Larry Smith <no_spam@_nospa m.com>
                wrote:
                >
                >>In C++, RAII provides a convenient way to deal with that, and in
                >>C#, the "using" statement does the same. You may prefer one syntax
                >>over the other, but I personally don't see a difference between the
                >>two that would
                >>justify an argument of superiority one way or the other
                >>
                >That's hardly a valid argument, considering that RAII requires no
                >"using" statement whatsoever. This alone justifies an argument that
                >there is a difference in favour of C++ (in contrast to your
                >assertion).
                >
                You save a whole line of code. Wow! Yup...that definitely outweighs
                any advantage that garbage collection has with respect to simplifying
                and improving the robustness of memory management. After all, that's
                what programmers really care about. I'd much rather save a line of
                code than make it more likely that my code is correct.
                The C# way is brittle. If C# let you use a using statement with types that
                don't support IDisposable, then it would be better. But right now, adding
                IDisposable support to an existing class is always an impermissible breaking
                change.

                In C++, you can add a destructor without any changes to the code which
                references the class.

                That's a much bigger issue than saving a single line of code.


                Comment

                • Ben Voigt [C++ MVP]

                  Re: learn C++ or C#

                  Peter Duniho wrote:
                  On Thu, 24 Jul 2008 11:23:49 -0700, David Wilkinson
                  <no-reply@effisols. comwrote:
                  >
                  >Not only is the "using" mechanism less convenient/elegant for the
                  >client of the class than RAII (not to mention the possibility of
                  >forgetting to do it), but a C# Dispose'd object can still be used
                  >(unlike a C++ object that goes out of scope or is delete'd).
                  >
                  I was comprehending your post until "or is delete'd". There's
                  nothing in C++ to stop someone from trying to use an object that's
                  been deleted, and depending on how the memory was allocated and what
                  the class does in its destructor, doing so might even work for awhile.
                  C++ delete calls the implementation of 'operator delete' after running the
                  destructor, which can mark the memory with a pattern (or on some CPUs, even
                  set up data breakpoints to trap any future access to that memory) which in
                  debug builds would detect use after free. You can use something like
                  electric fence which will deallocate the segment, generating a segfault on
                  any future access to that object. All of which can be done without any
                  changes to the class being protected.

                  So no, these aren't "in C++", because one of the prime ideals of C++ is "you
                  don't pay for what you don't use". You turn on these features during
                  debugging, and perhaps in extremely critical environments where failure
                  detection is more important than efficiency you might leave them on in the
                  release build. In all other circumstances, you convince yourself through
                  thorough testing that these sorts of bugs have been eliminated, and disable
                  the checks.


                  Comment

                  • Peter Duniho

                    Re: learn C++ or C#

                    On Thu, 24 Jul 2008 15:14:38 -0700, Ben Voigt [C++ MVP]
                    <rbv@nospam.nos pamwrote:
                    >>Destructor and "scope" syntax in C++ is cleaner, simpler and more
                    >>elegant than C# bloated 'using'.
                    >>
                    >Purely subjective. That sort of claim has no place in a technical
                    >discussion.
                    >
                    It's quite objective. In C++, the burden is on the library developer,
                    the
                    user needs no extra syntax to benefit from automatic cleanup.
                    You don't seem to have read the statements you quoted.

                    I'm talking about the question of the syntax itself, not the semantics.
                    The need to include a "using" statement is not a "burden". It's just a
                    different way to write the same thing.
                    [...]
                    >As I pointed out before, in a 100% GC-ed system, "smart pointers"
                    >become unnecessary anyway. But in a mixed system (i.e. pretty much
                    >
                    Nothing could be further from the truth.
                    Ah, more hyperbole. Yup...that really makes your point compelling.
                    Lazy (or deferred, if you prefer)
                    cleanup breaks access to shared resources, and does so
                    non-deterministical ly.
                    In a 100% GC-ed system, a resource that's eligible for "cleanup" is not
                    "shared" by any code anywhere, by definition. Your statement makes no
                    sense.
                    >any current platform), it's entirely possible to implement "smart
                    >pointers", and they can work in a very similar way to that
                    >implemented with RAII.
                    >
                    No, in C# it's not possible to create an object that automatically
                    performs
                    cleanup when it becomes unreachable.
                    I never said it was. But nice straw man.

                    Pete

                    Comment

                    • Peter Duniho

                      Re: learn C++ or C#

                      On Thu, 24 Jul 2008 15:17:05 -0700, Ben Voigt [C++ MVP]
                      <rbv@nospam.nos pamwrote:
                      The C# way is brittle. If C# let you use a using statement with types
                      that
                      don't support IDisposable, then it would be better. But right now,
                      adding
                      IDisposable support to an existing class is always an impermissible
                      breaking
                      change.
                      >
                      In C++, you can add a destructor without any changes to the code which
                      references the class.
                      If C++ didn't have its own brittle behaviors (including limitations on the
                      use of stack-allocated classes), I might think your point has some merit
                      here.

                      But it does, so I don't.

                      Pete

                      Comment

                      • Peter Duniho

                        Re: learn C++ or C#

                        On Thu, 24 Jul 2008 15:22:47 -0700, Ben Voigt [C++ MVP]
                        <rbv@nospam.nos pamwrote:
                        [...essay on C++ built-in testing aids...]
                        In all other circumstances, you convince yourself through
                        thorough testing that these sorts of bugs have been eliminated, and
                        disable
                        the checks.
                        Yes, I'm aware of all of the debugging aids C++ includes so that you can
                        hopefully detect coding errors that simply aren't possible in C#.

                        As far as I'm concerned, you're just making my point for me.

                        Comment

                        • Andre Kaufmann

                          Re: learn C++ or C#

                          Peter Duniho wrote:
                          On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
                          <andre.kaufmann _re_move_@t-online.dewrote:
                          >
                          [...]
                          But you can include reference counting in the C# object if you want.
                          You can even implement a "smart pointer" class that uses Dispose() to
                          decrement the counter and call Dispose() on the wrapped object if it
                          reaches 0.
                          I can include reference counting, but I can't use smart pointers. I
                          prefer GC memory handling, but for resources GC can't be used
                          effectively, because often resources have to be released directly.
                          I do a lot of multi threaded programming, there I permanently have the
                          need of some kind of reference counted resource handling.

                          [...]
                          But there's nothing about C# that precludes using that
                          technique if you find yourself i
                          If you could add methods to value structures in C# I would agree. But
                          currently in C# you have to either use a temporary object in combination
                          with using or call the AddRef / Release functions by hand.

                          Perhaps it wouldn't be a good idea to add the complexity of C++ which
                          allows RAII to C#, but some kind of simple automatism would IMHO help too.

                          E.g. the temporary objects could be replaced by some kind of using which
                          calls specified methods of an object.

                          Pseudo code:

                          MyObject o; // member variable
                          ....
                          autocall(o) --calls enter / leave methods automatically
                          { // call o.enter()
                          } // call o.leave()

                          Pete
                          Andre

                          Comment

                          • Peter Duniho

                            Re: learn C++ or C#

                            On Thu, 24 Jul 2008 22:43:52 -0700, Andre Kaufmann
                            <andre.kaufmann _re_move_@t-online.dewrote:
                            Peter Duniho wrote:
                            >On Thu, 24 Jul 2008 12:30:34 -0700, Andre Kaufmann
                            ><andre.kaufman n_re_move_@t-online.dewrote:
                            > [...]
                            >But you can include reference counting in the C# object if you want.
                            >You can even implement a "smart pointer" class that uses Dispose() to
                            >decrement the counter and call Dispose() on the wrapped object if it
                            >reaches 0.
                            >
                            I can include reference counting, but I can't use smart pointers.
                            Why not?
                            I prefer GC memory handling, but for resources GC can't be used
                            effectively, because often resources have to be released directly.
                            I do a lot of multi threaded programming, there I permanently have the
                            need of some kind of reference counted resource handling.
                            For what it's worth, I've done a fair amount of multi-threaded programming
                            in C# without needing ref-counting.

                            Not that I agree that ref-counting can't be done in C#, but I've found
                            that in many cases, what's really needed is a different way of looking at
                            the problem.
                            >[...]
                            But there's nothing about C# that precludes using that
                            technique if you find yourself i
                            >
                            If you could add methods to value structures in C# I would agree.
                            I don't know what you mean here. What methods do you want to add? To
                            what structure? How would that help?
                            But currently in C# you have to either use a temporary object in
                            combination with using or call the AddRef / Release functions by hand.
                            How is a smart pointer not a temporary object?
                            Perhaps it wouldn't be a good idea to add the complexity of C++ which
                            allows RAII to C#, but some kind of simple automatism would IMHO help
                            too.
                            >
                            E.g. the temporary objects could be replaced by some kind of using which
                            calls specified methods of an object.
                            >
                            Pseudo code:
                            >
                            MyObject o; // member variable
                            ....
                            autocall(o) --calls enter / leave methods automatically
                            { // call o.enter()
                            } // call o.leave()
                            Why not just create a smart-pointer-like class or struct that does that
                            with the "using" statement? Adds a ref when the object is created,
                            decrements the ref on disposal, zero ref-count causes disposal of the
                            wrapped object.

                            Maybe I'm just being obtuse, but I don't see what the big problem is.

                            Pete

                            Comment

                            • Daniel James

                              Re: learn C++ or C#

                              In article news:<OdstKlU7I HA.1952@TK2MSFT NGP02.phx.gbl>, Mc wrote:
                              Yes... the big difference is that with C#, errors manifest themselves
                              as incorrect output or recognizable error messages rather than random
                              crashes or memory leaks.
                              At least you KNOW there's something wrong when you get a random crash ...
                              that incorrect output you get from your C# program is really much more
                              dangerous.

                              I think you and Larry and others here blowing the C# trumpet are vastly
                              over-stating the case about C++ being hard to use and hard to get right.
                              The fact is that bad programmers will write bad code in any language, and
                              if you want good code you have to employ good programmers. Once you have
                              those your problems will start to go away -- whatever language you are
                              using.

                              Of course, you need good management, too. Bad management and irrational
                              budgetary constraints can ruin a project just as easily as bad programming.

                              Cheers,
                              Daniel.


                              Comment

                              • Daniel James

                                Re: learn C++ or C#

                                In article news:<OPjv4tY7I HA.2072@TK2MSFT NGP04.phx.gbl>, Larry Smith wrote:
                                I also have some serious pet peeves. Why didn't they permit local
                                classes to be passed as template arguments. I once asked Stroustrup
                                about this at a conference but I wasn't satisfied with his terse
                                response.
                                I think the answer to that is "it looked too hard at the time" ... and IIRC
                                that constraint is to be removed an some future version of the standard.

                                I certainly agree that the ability to use a local class as an argument
                                would make the use of for_each much more natural.
                                C# allows me to use anonymous methods which is so
                                much cleaner
                                You can achieve the same sort of effect with boost::lambda
                                Even very experienced developers have to continuously bend their
                                minds out of shape and remain on guard years after learning the
                                language. This is not the hallmark of a successful language in
                                spite of C++'s "stellar" reputation and the millions who
                                continue struggling with it.
                                I think it's /only/ the very experienced developers (and those who aren't
                                but think they are -- which is more worrying) who "continuous ly bend their
                                minds out of shape" looking for new ways to use the expressive power of the
                                language. These are the library builders, the Boost developers, the
                                Alexandrescus of the world ... most C++ programmers just /use/ their work
                                and are grateful for the way that it makes their lives easier and more
                                pleasant.

                                Cheers,
                                Daniel.



                                Comment

                                Working...