Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    try catch finally - when doc->StartUndo()

    SDK Help
    0
    19
    1.4k
    Loading More Posts
    • 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.
    • H
      Helper
      last edited by

      On 06/08/2013 at 11:24, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:    
      Platform:      
      Language(s) :

      ---------
      I use try-catch-finally ALL the time when programming in Delphi and C#.
      For my plugins in C++, I haven't used it so far. All the examples in the SDK, I find no such thing..(?)
      Does it exist in C++?

      Take this scenario

        doc->StartUndo();
        do_something
        do_something_else
        something_goes_wrong
        do_the_final_thing
        doc->EndUndo();
      

      I am responsible for calling doc->EndUndo(), when I have called StartUndo(), right?
      I am interested to know how you guys solve this.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 06/08/2013 at 16:43, xxxxxxxx wrote:

        Oh yes.  C++ has try-catch-all (no finally).  But, Cinema 4D's SDK does not directly support exception handling.  So, if you do use them, you must catch EVERY exception or it will wind back to the c4d_main of the plugin and crash Cinema 4D.  A suggestion on StackOverflow uses this construct (catch the exceptions you know about, then catch everything else) :

          
            
            
            try{
                // ...
            } catch (const std::exception& ex) {
                // ...
            } catch (const std::string& ex) {
                // ...
            } catch (...) {
                // ...
            }
        
        For StartUndo()/EndUndo(), to avoid early returns in a method, I wrap a method with these like so:  
        
          
            doc->StartUndo();  
            Bool retval = DoStuffThatHasUndos();  
            doc->EndUndo();  
            if (!retval) return;
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 06/08/2013 at 17:03, xxxxxxxx wrote:

          Hi,
          for the latter, I have already done that, so I can cater for the EndUndo();
          But regarding the exception handling, or the lack of such, I am still a bit confused.

          Take this:

          	int a = 123;
          	int b = 0;
          	try
          	{
          		int c = a / b;
          	}
          	catch(std::exception &e)
          	{
          		MessageDialog("Something went wrong");
          	}
          

          The MessageDialog never fires, instead Cinema will crash, regardless of wrapping this in a try - catch.
          How can I wrap stuff in a way that prevents a crash, and furthermore executes some code, in this case a simple message dialog?

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 06/08/2013 at 17:50, xxxxxxxx wrote:

            You really need to include the catch-all (catch (...)).  It is not guaranteed that every exception is derived from 'exception' or that it will be caught specifically.  See here:

            http://stackoverflow.com/questions/6121623/catching-exception-divide-by-zero

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 06/08/2013 at 18:31, xxxxxxxx wrote:

              Hi Robert,
              thanks a lot! This was an important lesson. I have never seen catch(...) before, honestly. I thought it was a symbol for some code, since you used the three dots elsewhere too, but indeed, those three periods compile like magic 😉

              As a plugin writer, wouldn't you wrap everything, any method, in a try catch-all block? I see that almost everything is tested before being used, in the SDK plugins. So I have adopted that habit myself too, rigorously. But as an extra safety, why not also wrap it up in a try catch-all block? Are there drawbacks?

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 06/08/2013 at 18:56, xxxxxxxx wrote:

                You can if you like.  It would make sense to have the try/catch on everything when exception handling is present.  Stuff that doesn't throw exceptions just executes as it normally would.  But since you can also catch errors (such as the overflow and such), it would even work for code that doesn't implement exception handling directly.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 07/08/2013 at 03:44, xxxxxxxx wrote:

                  It would make sense to have the try/catch on everything when exception handling is present.

                  Really ? 
                  I don't think this is a good idea.

                  IMHO  Exception should be used only if really really needed and as rare as possible.

                  Why not use RAII for this ?

                    
                  class UndoRAII  
                  {  
                    BaseDocument *m_doc;  
                  public:   
                    UndoRAII(BaseDocument *doc) : m_doc(doc) {}  
                    ~UndoRAII() { doc->EndUndo(); }  
                  }  
                  

                  And the use in this way.

                    
                      
                      
                      {  
                        doc->StartUndo();  
                        UndoRAII undo_end1(doc);  
                        
                      
                      
                        do_something
                      
                        do_something_else
                      
                        something_goes_wrong
                      
                        do_the_final_thing  
                      }  
                      
                    
                  
                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 07/08/2013 at 04:11, xxxxxxxx wrote:

                    While I agree, if you are wanting to handle STL exceptions (and errors) you may want to brace code that has those possibilities - such as mathematical algorithms and such beyond the normal STL exceptions.  Otherwise, I have never seen any problems in bracing larger sections of code.  There might be a very small speed hit at most.

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 07/08/2013 at 04:27, xxxxxxxx wrote:

                      Originally posted by xxxxxxxx

                      It would make sense to have the try/catch on everything when exception handling is present.
                      Really ?  
                      I don't think this is a good idea.

                      I agree with Robert here. It is a very good idea in C#, so why not in C++?
                      "Things" will invariably happen, especially when users  are involved, - and they usually are.

                      -Ingvar

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 07/08/2013 at 04:46, xxxxxxxx wrote:

                        Yeah, i actually did that in order to deal with failed memory allocations and IO errors in my current project. Basically try/catch around some complicated computations. If e.g. std::bad_alloc is caught it would just unwind to the top level function and return INITRENDER_OUT_OF_MEMORY, without me having to clutter my code with checks for every little allocation 🙂

                        Don't forget to enable exception handling in the compiler options though. It is disabled by default.

                        Also, none of the C4D API functions throws exceptions, so you have to check for errors manually or write wrappers which throw exceptions.

                        For something like the Undo, you could also use a pattern where some arbitrary code is executed on scope exit but without having to write a special class for RAII. For example http://code.google.com/p/scope-exit/
                        or http://www.boost.org/doc/libs/1_54_0/libs/scope_exit/doc/html/index.html I never tried it but i figured it should work nicely with c++11 lambdas, etc.

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 07/08/2013 at 06:13, xxxxxxxx wrote:

                          I think that both Visual Studio and Xcode will error during compilation if there is exception syntax and exception handling isn't enabled.  But good to note that it needs to be enabled nonetheless.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            On 07/08/2013 at 06:25, xxxxxxxx wrote:

                            I have exception syntax and do not get an error. And I have never turned exception handling on, in fact, I have no idea how it is done in Visual Studio. I take it for granted it is on..

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              On 07/08/2013 at 07:37, xxxxxxxx wrote:

                              Sorry, i meant it is disabled in the cinema4dsdk project. In VC it is just a warning if exception syntax is used while compiler support is disabled.
                              The setting is in the project properties page Configuration Properties/C/C++/Code Generation/Enable C++ Exceptions.

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                On 08/08/2013 at 00:02, xxxxxxxx wrote:

                                Originally posted by xxxxxxxx

                                I agree with Robert here. It is a very good idea in C#, so why not in C++?

                                Some food for thought why you should avoid exceptions whenever possible (and that 's just the beginning if you dig into it) :

                                http://c2.com/cgi/wiki?AvoidExceptionsWheneverPossible
                                http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl
                                http://programmers.stackexchange.com/questions/107723/arguments-for-or-against-using-try-catch-as-logical-operators
                                http://stackoverflow.com/questions/1744070/why-should-exceptions-be-used-conservatively

                                Best regards,

                                Wilfried

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  On 08/08/2013 at 00:24, xxxxxxxx wrote:

                                  Right, but if you use anything (a third-party lib or the STL) that requires exception handling, then you MUST handle them or suffer the consequences (Cinema 4D crashes).  Not much choice there.

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    On 08/08/2013 at 01:14, xxxxxxxx wrote:

                                    Originally posted by xxxxxxxx

                                    Right, but if you use anything (a third-party lib or the STL) that requires exception handling, then you MUST handle them or suffer the consequences (Cinema 4D crashes).  Not much choice there.

                                    Maybe a requirement for 3rd party libs but not necessarily for STL. For Win I know that you can turn it off (you've to use the #define _HAS_EXCEPTIONS 0 #define _STATIC_CPPLIB besides switching off exceptions) and for OS X I'm pretty sure you can too, as the LLVM compiler project (while using STL) has the rule of not using RTTI or exceptions (see: http://llvm.org/docs/CodingStandards.html#do-not-use-rtti-or-exceptions) :

                                    "These two language features violate the general C++ principle of "you only pay for what you use", causing executable bloat even if exceptions are never used in the code base, or if RTTI is never used for a class. Because of this, we turn them off globally in the code."

                                    Best regards,

                                    Wilfried

                                    1 Reply Last reply Reply Quote 0
                                    • H
                                      Helper
                                      last edited by

                                      On 08/08/2013 at 02:06, xxxxxxxx wrote:

                                      Never knew about that (but then I don't use exception handling very often).  How is error handling done then?  Does this switch to an alternative codebase that returns errors instead?

                                      1 Reply Last reply Reply Quote 0
                                      • H
                                        Helper
                                        last edited by

                                        On 08/08/2013 at 03:35, xxxxxxxx wrote:

                                        Yes scope-exit can be very helpful, but only if you use C++11.

                                        Here is how I would do it using my SCOPE_EXIT implementation.

                                          
                                        doc->StartUndo();  
                                        SCOPE_EXIT  { doc->EndUndo(); }  
                                        ...  
                                        

                                        1 Reply Last reply Reply Quote 0
                                        • H
                                          Helper
                                          last edited by

                                          On 08/08/2013 at 03:39, xxxxxxxx wrote:

                                          Ok, I am not using exceptions as type checking or value approval. I use try-catch in case something goes wrong which I had not thought of beforehand.
                                          Some very good programmers will foresee any possible event and any bad function argument and any peculiar user behaviour and write the appropriate code to tackle this.
                                          While I am not such a good programmer, I instead type check and validate values as best as I can, then I want to wrap it up in try-catch for final safety. I just do not want my plugins to crash C4D.

                                          In C#, which is my job (C4D plugins is a hobby), everything  I write is wrapped in try-catch, sometimes also -finally. Mostly I benefit from this during development and debugging, because if reflection in C#, I immediately know what went wrong, and at what line in what class in what file it happened. The gioal is of course to have as few exceptions as possible in the final product. 
                                          And I have very seldom used exceptions to steer the program flow.

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post