Thread: To throw or not to throw

  1. #31
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by phantomotap View Post
    Nope. I specifically said "However, we expect that we may be reading the last bits of the stream so `eofbit' is not an error.".
    In that case, what point were you trying to make with that long winded post?
    Why are you checking the badbit after getting an exception? The whole point of the exception is to deliever the bad news, and alleviate the need to call to bad(). What an awful hodgepodge.

    Quote Originally Posted by phantomotap View Post
    You did a fantastic job breaking the code!

    You've forced the client to report an error (The `err' in `std::cerr' stands for "error".) even if the situation is actually normal from the client's perspective.

    The client can't now treat the configuration file missing as a normal occurrence.
    stderr was indeed create with errors in mind, but it's nowadays commonly used for any auxillary non-error output; *nix doesn't have stdaux or stdwarn.
    So, it's fine to write to stderr but still return success to a caller.


    If you are serious about "handling" exceptions internally with a log trace, what are you going to do if `getDefaultConfig' raises an exception?
    As you know, loadConfigFileOrDefaults() would unwind then. But that's okay, because the caller expects (as the function is so name) configuration to be loaded from the file or defaults. There's nothing wrong with that, it's all well and expected.

    Edit: Though, if getDefaultConfig can throw, it may be appropriate to call it before the warning is reported.
    Last edited by Yarin; 01-24-2015 at 02:12 PM.

  2. #32
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Why are you checking the badbit after getting an exception? The whole point of the exception is to deliever the bad news, and alleviate the need to call to bad().
    o_O

    You actually don't read your own comments.

    The `std::ios' components allow you to specify which error states raise an exception.

    In other words, the `std::ios' components "conditionally throw an exception" which is a "is a recipe for disaster" according to you.

    If the `std::ios' components didn't "conditionally throw an exception", you would have to idiotically filter the exceptions or examine the return codes as my examples show to ignore the spurious `EOF' situation while still reporting other erros.

    Only because the `std::ios' components "conditionally throw an exception", I do not need to idiotically filter irrelevant exceptions or examine return codes for problems I can't handle.

    Code:
    void DoSomething
    (
        std::istream & f
    )
    {
        IOSState sRollback(f);
        sRollback.exceptions(badbit);
        int sValue;
        while(f >> sValue) // We allow the exception to
        {
            // We can use `sValue' as we need.
        }
        // We can do more stuff.
    }
    Thanks to the `std::ios' components "conditionally throw an exception" aspect, I'm only writing code for the situations I care about.

    I am not required to "write the code for both approches".

    You are simply spewing nonsense.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  3. #33
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by phantomotap View Post
    The `std::ios' components allow you to specify which error states raise an exception.

    In other words, the `std::ios' components "conditionally throw an exception" which is a "is a recipe for disaster" according to you.

    If the `std::ios' components didn't "conditionally throw an exception", you would have to idiotically filter the exceptions or examine the return codes as my examples show to ignore the spurious `EOF' situation while still reporting other erros.

    Only because the `std::ios' components "conditionally throw an exception", I do not need to idiotically filter irrelevant exceptions or examine return codes for problems I can't handle.
    It's a solution is search of a problem.


    Quote Originally Posted by phantomotap View Post
    I am not required to "write the code for both approches".
    Nor is one required to when using, for example, posix read(). It returns 0 on EOF, no option to make it an error. Yet, escalating it to an error if you so wish is very easy. No "ios" equivalent needed (or wanted)!


    Quote Originally Posted by phantomotap View Post
    You are simply spewing nonsense.
    I like to use simple solutions to solve simple problems. Sue me.

  4. #34
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    As you know, loadConfigFileOrDefaults() would unwind then. But that's okay, because the caller expects (as the function is so name) configuration to be loaded from the file or defaults. There's nothing wrong with that, it's all well and expected.
    O_o

    Exactly.

    [Edit]
    There is nothing wrong with swallowing the exception from `loadConfig' without forcing the trace on the client because "it's all well and expected" that `loadConfig' might fail.
    [/Edit]

    It's a solution is search of a problem.
    o_O

    The optional mechanism raising an exception can be a perfect answer to the "Should an interface return an error code or raise an exception?" question.

    You aren't forced to do just one or the other; you can do both allowing the client to choose according to the situation.

    Nor is one required to when using, for example, posix read(). It returns 0 on EOF, no option to make it an error. Yet, escalating it to an error if you so wish is very easy.
    I didn't say that you would have to write code for both approaches.

    You are the one responsible for posting that nonsense.

    No "ios" equivalent needed (or wanted)!
    Certainly.

    I don't directly use the `std::ios' components or "POSIX" interfaces.

    I'm not trying to force you.

    I like to use simple solutions to solve simple problems.
    Wonderful.

    I like to use the simple solutions to any problem I face.

    Happily, an optional mechanism raising an exception allows you to inspect your return code while I don't have to ........ about transforming a return code into an exception.

    We both get to use our simple solutions without writing crappy boilerplate code.

    Yay!

    Soma
    Last edited by phantomotap; 01-24-2015 at 02:56 PM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #35
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    Quote Originally Posted by phantomotap View Post
    I didn't say that you would have to write code for both approaches.

    You are the one responsible for posting that nonsense.
    You might have misunderstood me.
    I never said loadConfigFileOrDefaults() is a nothrow/nofail/safe version of loadConfigFile(). (That is, the "second approach")
    I simply meant it as an example as to how you don't need a "second approach", when you can handle errors thrown by the "first approach" with ease.

  6. #36
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    In my line of work, we often have to run jobs that involve the processing of terabytes of data. These jobs can run for several days before finishing, even when optimized.

    If a job like this gets terminated due to an error, you don't really have the option of running it a second time in an access checker to get the stack trace for the bug, because it could take weeks for the problem to turn up. Clients don't tend to want to wait that long for their data to be processed.

    So I have gotten into the habit of using exceptions to provide manually constructed stack traces in the event of an error. There are a couple of ways of doing this. One way is GCC's "backtrace" function, which is handy -- but also not in the C++ standard.

    The alternative is wrapping every single one of your functions in a function try block and putting some code in the function catch block that adds the name of that function to the exception. Typically the exception will be an instance of some std::exception-derived class, with a constant-length char[] array embedded in it, to hold the stack trace.

    The latter approach is the way I have gone. It is horrendously inelegant, and makes your code as ugly as hell. But it might save your life when some massive job gets 96% of the way through and then bombs out on you.

    A word of warning -- if you are going to use this kind of approach to build stack traces, you are going to need to write yourself code to format the exception. This code will need to be designed to execute only when there is already an active exception. This means it should be written in C to make sure a second exception can't be thrown during formatting. This is why I used an embedded char[] array, instead of an std::string object whose operator+() might throw on you. The std::current_exception() function is a good way to make sure that the error-handling code can't be called by mistake when no exception exists.

    [Edit: For "written in C" above, read "written using noexcept functions". Std::current_exception obviously is not a C function.]

  7. #37
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Most operating systems have a way of getting a backtrace. E.g., for windows.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #38
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    Quote Originally Posted by Elysia View Post
    Most operating systems have a way of getting a backtrace. E.g., for windows.
    When they come up with one in the C++ standard I will very gladly start using it.

    Same goes for GCC's PRETTY_FUNCTION macro, by the way.

  9. #39
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Until then you're just going to have to do like everyone else does: use platform specific APIs and hide those behind an interface. Unless some platforms you're working on does not support getting backtraces via some API, this is the easiest method.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. throw in function name
    By l2u in forum C++ Programming
    Replies: 10
    Last Post: 07-28-2008, 12:37 PM
  2. Throw away the key!
    By Salem in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 06-12-2008, 08:28 PM
  3. Why does C++ need throw()
    By meili100 in forum C++ Programming
    Replies: 19
    Last Post: 11-10-2007, 12:34 PM
  4. function throw
    By l2u in forum C++ Programming
    Replies: 3
    Last Post: 04-30-2007, 08:09 AM
  5. re-throw an exception
    By filler_bunny in forum C++ Programming
    Replies: 7
    Last Post: 10-15-2003, 06:06 AM