Throwing exceptions from copy constructor

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

    Throwing exceptions from copy constructor

    People say that is a bad technique to throw exception from
    constructors; and that the solution would be to create a function
    _create_ to initialize an object.

    What about copy constructors? How can we avoid throwing exceptions? If
    we already have an abject witch was initialized wit _create_ we will be
    forced to call create in copy constructor and to throw exceptions from
    it.

    Have a nice day,
    Mihai.

  • James Daughtry

    #2
    Re: Throwing exceptions from copy constructor

    >People say that is a bad technique to throw exception from constructors
    In an ideal world, constructors would never throw. In the real world,
    that's not the case. Whether bad technique or not (I won't step on a
    slippery slope like that), a non-trivial class will likely see a
    situation where it could need to catch an exception caused by
    construction of either a base class or one of the data members, and not
    be able to reasonably handle it.

    What would you do in that case? Complain that throwing from
    constructors is bad style and do nothing? Sure, you could use a create
    function to initialize the object, but if you call it in the
    constructor and it throws, you're back to square one. That leaves
    calling it outside of the constructor, which basically means that you
    either require the client code to call it (a dangerous plan), or you
    work out some ugly hack where create is only called for the first use
    beyond the constructor.

    What about default initialization? It's feasable that default
    initialization could fail, and since that constitutes an exceptional
    situation, the constructor could throw (bad style or not). So you find
    yourself between a rock and a hard place with the ideal world and the
    real world. And here's the bad news: The real world always wins.

    This includes the copy constructor and in some cases the assignment
    operator as well. I hate to say that you're SOL, but them's the breaks.

    Comment

    • John Carson

      #3
      Re: Throwing exceptions from copy constructor

      "mihai" <Mihai.Grecu@gm ail.com> wrote in message
      news:1117712863 .931778.290700@ g44g2000cwa.goo glegroups.com[color=blue]
      > People say that is a bad technique to throw exception from
      > constructors; and that the solution would be to create a function
      > _create_ to initialize an object.
      >
      > What about copy constructors? How can we avoid throwing exceptions? If
      > we already have an abject witch was initialized wit _create_ we will
      > be forced to call create in copy constructor and to throw exceptions
      > from it.[/color]


      I don't believe that well-informed people say constructors shouldn't throw.
      They do say that *destructors* shouldn't throw.

      The throwing of an exception by a constructor can cause a problem because it
      means that the destructor is not called, which may mean that necessary
      cleanup doesn't occur.

      The standard way to handle this is to wrap anything in class A that needs to
      be cleaned up in a class of its own (say, classes B, C and D) and then make
      objects of those classes (say, b, c and d) members of A. The initialisation
      of b, c and d can then occur in A's constructor (via the initialisation
      list). If, say, the initialisation of d causes an exception, then b and c
      will have been fully constructed (unlike the A object) and hence their
      destructors will be called, even though the A object's constructor won't be.
      This achieves the necessary cleanup.

      The C++ FAQ on Exceptions and Error Handling has some useful stuff on this:



      --
      John Carson

      Comment

      • BigBrian

        #4
        Re: Throwing exceptions from copy constructor

        IMHO, that's silly ( saying that it's bad technique to throw from a
        constructor ). What other mechanism is there to know if something goes
        wrong with contructing an object? You can't return an error code from
        the constructor, all you can do is throw an exception. Who said that
        this is bad technique anyway?

        Comment

        • Alf P. Steinbach

          #5
          Re: Throwing exceptions from copy constructor

          * BigBrian:[color=blue]
          >
          > IMHO, that's silly ( saying that it's bad technique to throw from a
          > constructor ).[/color]

          Yes.

          [color=blue]
          > What other mechanism is there to know if something goes
          > wrong with contructing an object?[/color]

          An infinite number... ;-)

          [color=blue]
          > You can't return an error code from the constructor, all you can do is
          > throw an exception.[/color]

          Nope.

          class Silly
          {
          private:
          bool iAmValid;

          public:
          Silly( int x, bool& ok ): iAmValid( x == 42 )
          {
          ok = iAmValid;
          }
          };

          The reason why this _particular_ technique is bad is mainly that you risk
          having invalid objects hanging around, so called ZOMBIE OBJECTS, which
          necessitates much redundant checking of validity and leads to bugs.

          Formally it's a kind of meta, second-level class invariant.

          Worth noting: languages like Java and C# typically force you to have
          zombie objects but in those languages the problem arises from the other end
          of the object lifecycle, destruction. Because you don't have deterministic
          destruction in those languages the programmer must call Dispose (or like)
          methods explicitly, and the objects still exist afterwards. And so must
          note for themselves that they're no longer valid, and so they're zombies
          and can conceivably become zombies earlier on.

          Also worth noting: handling of external resources in some cases require
          zombie states. E.g., a file can become invalid at any time. An object
          wrapping that file is then logically invalid for at least part of its
          interface, a zombie object wrt. to the invalid parts of the interface.

          [color=blue]
          > Who said that [throwing an exception] is bad technique anyway?[/color]

          Yes. Anyone worth listening to will tell the opposite. A clear but
          limited discussion of why using exceptions in constructors, avoiding
          zombie states, is given in Bjarne Stroustrup's TCPPPL appendix on
          exception safety in the standard library, available as a PDF document
          at <url: http://www.research.at t.com/~bs/3rd_safe0.html> .

          --
          A: Because it messes up the order in which people normally read text.
          Q: Why is it such a bad thing?
          A: Top-posting.
          Q: What is the most annoying thing on usenet and in e-mail?

          Comment

          • Amit

            #6
            Re: Throwing exceptions from copy constructor


            "mihai" <Mihai.Grecu@gm ail.com> wrote in message
            news:1117712863 .931778.290700@ g44g2000cwa.goo glegroups.com.. .[color=blue]
            > People say that is a bad technique to throw exception from
            > constructors; and that the solution would be to create a function
            > _create_ to initialize an object.[/color]

            The so called bad technique is throwing exception from destructors, not
            constructors.
            [color=blue]
            >
            > What about copy constructors? How can we avoid throwing exceptions? If
            > we already have an abject witch was initialized wit _create_ we will be
            > forced to call create in copy constructor and to throw exceptions from
            > it.[/color]

            There are many ways like turning your object into a zombie state. Read the
            FAQ, it describes some of the techniques.
            Of course, throwing exceptions from copy consturcotrs is what most would
            recommend.
            [color=blue]
            >
            > Have a nice day,
            > Mihai.
            >[/color]


            Comment

            • BigBrian

              #7
              Re: Throwing exceptions from copy constructor

              Yes, I guess somebody could do something like your Silly class, however
              since it has problems I didn't consider this when I made my statement
              about "what other mechanism exist (for notifying the client code that
              an error has occured in a constructor)". In using the Silly class, the
              calling code may not check the pass by reference value into this
              constructor. Also, the silly class will need a bunch of if tests
              throughout it's implementation.

              Since you said there are infinitely many ways to provide this
              mechanism, and the Silly class is clearly not the way to do it. Please
              provide another method which is better than throwing an exception.

              I understand that some objects need memebers to keep track of some sort
              of state, and that state may at times be invalid. This is different
              than error conditions which need to throw exceptions to notify the
              calling code that something is wrong.

              Comment

              • BigBrian

                #8
                Re: Throwing exceptions from copy constructor

                >The so called bad technique is throwing exception from destructors, not
                constructors.

                I thought throwing an exception from a destructor was *MUCH* worse than
                bad technique, it's plain outright WRONG. Aren't destructors REQUIRED
                to NOT throw?

                Comment

                • Alf P. Steinbach

                  #9
                  Re: Throwing exceptions from copy constructor

                  * BigBrian:[color=blue]
                  > Yes, I guess somebody could do something like your Silly class, however
                  > since it has problems I didn't consider this when I made my statement
                  > about "what other mechanism exist (for notifying the client code that
                  > an error has occured in a constructor)". In using the Silly class, the
                  > calling code may not check the pass by reference value into this
                  > constructor. Also, the silly class will need a bunch of if tests
                  > throughout it's implementation.[/color]

                  That's about right.

                  [color=blue]
                  > Since you said there are infinitely many ways to provide this
                  > mechanism, and the Silly class is clearly not the way to do it. Please
                  > provide another method which is better than throwing an exception.[/color]

                  You'll need to define "better" first.

                  But it's evident that you've misunderstood and skipped some points, so
                  there's no real need for that: do read my posting again.

                  [color=blue]
                  > I understand that some objects need memebers to keep track of some sort
                  > of state, and that state may at times be invalid.[/color]

                  Yes, sort of.

                  [color=blue]
                  > This is different than error conditions which need to throw exceptions
                  > to notify the calling code that something is wrong.[/color]

                  No, it's all about convenience, maintainability , productivity and so forth.
                  There's no absolute "need", just as there is no absolute "better". Those
                  are subjective, contextual judgements, not technical facts, although I
                  agree that concerning this issue you'd need very strong reasons for using
                  anything but exceptions and be able to justify it to someone competent.

                  --
                  A: Because it messes up the order in which people normally read text.
                  Q: Why is it such a bad thing?
                  A: Top-posting.
                  Q: What is the most annoying thing on usenet and in e-mail?

                  Comment

                  • Alf P. Steinbach

                    #10
                    Re: Throwing exceptions from copy constructor

                    * BigBrian:[color=blue][color=green]
                    > > The so called bad technique is throwing exception from destructors, not
                    > > constructors.[/color]
                    >
                    > I thought throwing an exception from a destructor was *MUCH* worse than
                    > bad technique, it's plain outright WRONG. Aren't destructors REQUIRED
                    > to NOT throw?[/color]

                    No.

                    But a destructor for an object used in a standard collection is required
                    to not throw.

                    That's also the case for exception object destructors... ;-)

                    --
                    A: Because it messes up the order in which people normally read text.
                    Q: Why is it such a bad thing?
                    A: Top-posting.
                    Q: What is the most annoying thing on usenet and in e-mail?

                    Comment

                    • BigBrian

                      #11
                      Re: Throwing exceptions from copy constructor

                      >No.
                      [color=blue]
                      >But a destructor for an object used in a standard collection is required
                      >to not throw.[/color]

                      I don't this this is strict enough. Most techniques for writing
                      exception safe code assumes that destructors to NOT throw.

                      Comment

                      • BigBrian

                        #12
                        Re: Throwing exceptions from copy constructor

                        >You'll need to define "better" first.

                        It was implied that "better" meant without the stated problems with
                        your "Silly" class.
                        [color=blue]
                        >But it's evident that you've misunderstood and skipped some points,
                        > so, there's no real need for that: do read my posting again.[/color]

                        You (arogantly) said there were infinate ways to do this, and now you
                        won't provide another mechanism?
                        [color=blue]
                        > No, it's all about convenience, maintainability , productivity and so forth.
                        >There's no absolute "need", just as there is no absolute "better".[/color]

                        If the need to inform the user of a class that an error has occured is
                        a *requirement*, then there *is* an absolute need. This brings us back
                        to the issue... How else can you *guarentee* that the user of your
                        class knows (without a doubt) that an error has occured. Requiring the
                        user of your class to check a flag isn't good enough (due to the issues
                        that we already discoussed). What are the infinitely many other ways
                        to guarentte this is accomplish without throwing an exception?

                        Comment

                        • Alf P. Steinbach

                          #13
                          Re: Throwing exceptions from copy constructor

                          * BigBrian:[color=blue][color=green]
                          > >No.[/color]
                          >[color=green]
                          > >But a destructor for an object used in a standard collection is required
                          > >to not throw.[/color]
                          >
                          > I don't this this is strict enough. Most techniques for writing
                          > exception safe code assumes that destructors to NOT throw.[/color]

                          You asked: "Aren't destructors REQUIRED to NOT throw?".

                          You get an answer to that, not to something else that you even now aren't
                          telling what is.

                          Please don't use all caps, please don't quote out of context, please
                          don't add your own imagined context to responses (I at least am not a
                          telepath: I don't know what the heck you're talking about).

                          --
                          A: Because it messes up the order in which people normally read text.
                          Q: Why is it such a bad thing?
                          A: Top-posting.
                          Q: What is the most annoying thing on usenet and in e-mail?

                          Comment

                          • Alf P. Steinbach

                            #14
                            Re: Throwing exceptions from copy constructor

                            * BigBrian:[color=blue][color=green]
                            > >You'll need to define "better" first.[/color]
                            >
                            > It was implied that "better" meant without the stated problems with
                            > your "Silly" class.
                            >[color=green]
                            > >But it's evident that you've misunderstood and skipped some points,
                            > > so, there's no real need for that: do read my posting again.[/color]
                            >
                            > You (arogantly) said there were infinate ways to do this[/color]

                            The part "said there were infinate ways to do this" is a lie; the
                            "arogantly" is meaningless applied to something that hasn't happened.

                            Don't lie, don't insinuate.

                            You asked: "What other mechanism is there to know if something goes
                            wrong with contructing an object?"

                            You got the answer: "An infinite number... ;-)"

                            These include the Silly class way, abort, callback, global status
                            variable, factory with null-pointer result, even writing the result
                            to a file or sending an e-mail -- use your imagination.

                            [color=blue]
                            > and now you won't provide another mechanism?[/color]

                            If you can be more clear about the C++ question, I'll try to help you.

                            [color=blue][color=green]
                            > > No, it's all about convenience, maintainability , productivity and so forth.
                            > > There's no absolute "need", just as there is no absolute "better".[/color]
                            >
                            > If the need to inform the user of a class that an error has occured is
                            > a *requirement*, then there *is* an absolute need. This brings us back
                            > to the issue... How else can you *guarentee* that the user of your
                            > class knows (without a doubt) that an error has occured. Requiring the
                            > user of your class to check a flag isn't good enough (due to the issues
                            > that we already discoussed). What are the infinitely many other ways
                            > to guarentte this is accomplish without throwing an exception?[/color]

                            There are _no_ ways that guarantee that.

                            In particular, an exception doesn't guarantee that; client code can
                            always nullify any guarantee you think you have.

                            Foo* p; try{ p = new Foo; } catch(...){}
                            // No guarantee here.

                            Hth.,

                            - Alf

                            --
                            A: Because it messes up the order in which people normally read text.
                            Q: Why is it such a bad thing?
                            A: Top-posting.
                            Q: What is the most annoying thing on usenet and in e-mail?

                            Comment

                            • Clark S. Cox III

                              #15
                              Re: Throwing exceptions from copy constructor

                              On 2005-06-02 09:04:34 -0400, "John Carson"
                              <jcarson_n_o_sp _am_@netspace.n et.au> said:
                              [color=blue]
                              > "mihai" <Mihai.Grecu@gm ail.com> wrote in message
                              > news:1117712863 .931778.290700@ g44g2000cwa.goo glegroups.com[color=green]
                              >> People say that is a bad technique to throw exception from
                              >> constructors; and that the solution would be to create a function
                              >> _create_ to initialize an object.
                              >>
                              >> What about copy constructors? How can we avoid throwing exceptions? If
                              >> we already have an abject witch was initialized wit _create_ we will
                              >> be forced to call create in copy constructor and to throw exceptions
                              >> from it.[/color]
                              >
                              >
                              > I don't believe that well-informed people say constructors shouldn't
                              > throw. They do say that *destructors* shouldn't throw.
                              >
                              > The throwing of an exception by a constructor can cause a problem
                              > because it means that the destructor is not called, which may mean that
                              > necessary cleanup doesn't occur.[/color]

                              Just to clarify, the destructor of that class isn't called, but the
                              destructors of any already constructed superclasses are.
                              [color=blue]
                              > The standard way to handle this is to wrap anything in class A that
                              > needs to be cleaned up in a class of its own (say, classes B, C and D)
                              > and then make objects of those classes (say, b, c and d) members of A.
                              > The initialisation of b, c and d can then occur in A's constructor (via
                              > the initialisation list). If, say, the initialisation of d causes an
                              > exception, then b and c will have been fully constructed (unlike the A
                              > object) and hence their destructors will be called, even though the A
                              > object's constructor won't be. This achieves the necessary cleanup.
                              >
                              > The C++ FAQ on Exceptions and Error Handling has some useful stuff on this:
                              >
                              > http://www.parashift.com/c++-faq-lite/exceptions.html[/color]


                              --
                              Clark S. Cox, III
                              clarkcox3@gmail .com

                              Comment

                              Working...