Using throw to replace return in C++ non-void functions












32















In C++ functions, is it a good practice to replace return with throw? For example, I have the following code



// return indices of two numbers whose sum is equal to target
vector<int> twoSum(vector<int>& nums, int target) {
for(int i=0; i<nums.size()-1; ++i)
for(int j=i+1; j<nums.size(); ++j)
{
if(nums[i] + nums[j] == target) return vector<int>{i, j};
}
// return vector<int>{};
throw "no solution";
}


The code above compiles with my GCC 7.2.










share|improve this question




















  • 12





    It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

    – François Andrieux
    Feb 15 at 16:21








  • 3





    Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

    – NathanOliver
    Feb 15 at 16:21






  • 25





    Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

    – 0x5453
    Feb 15 at 16:21








  • 6





    Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

    – James Adkison
    Feb 15 at 16:22








  • 9





    Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

    – François Andrieux
    Feb 15 at 16:22


















32















In C++ functions, is it a good practice to replace return with throw? For example, I have the following code



// return indices of two numbers whose sum is equal to target
vector<int> twoSum(vector<int>& nums, int target) {
for(int i=0; i<nums.size()-1; ++i)
for(int j=i+1; j<nums.size(); ++j)
{
if(nums[i] + nums[j] == target) return vector<int>{i, j};
}
// return vector<int>{};
throw "no solution";
}


The code above compiles with my GCC 7.2.










share|improve this question




















  • 12





    It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

    – François Andrieux
    Feb 15 at 16:21








  • 3





    Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

    – NathanOliver
    Feb 15 at 16:21






  • 25





    Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

    – 0x5453
    Feb 15 at 16:21








  • 6





    Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

    – James Adkison
    Feb 15 at 16:22








  • 9





    Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

    – François Andrieux
    Feb 15 at 16:22
















32












32








32


1






In C++ functions, is it a good practice to replace return with throw? For example, I have the following code



// return indices of two numbers whose sum is equal to target
vector<int> twoSum(vector<int>& nums, int target) {
for(int i=0; i<nums.size()-1; ++i)
for(int j=i+1; j<nums.size(); ++j)
{
if(nums[i] + nums[j] == target) return vector<int>{i, j};
}
// return vector<int>{};
throw "no solution";
}


The code above compiles with my GCC 7.2.










share|improve this question
















In C++ functions, is it a good practice to replace return with throw? For example, I have the following code



// return indices of two numbers whose sum is equal to target
vector<int> twoSum(vector<int>& nums, int target) {
for(int i=0; i<nums.size()-1; ++i)
for(int j=i+1; j<nums.size(); ++j)
{
if(nums[i] + nums[j] == target) return vector<int>{i, j};
}
// return vector<int>{};
throw "no solution";
}


The code above compiles with my GCC 7.2.







c++ exception-handling






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 15 at 20:32









mrflash818

6861218




6861218










asked Feb 15 at 16:19









user27490user27490

34837




34837








  • 12





    It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

    – François Andrieux
    Feb 15 at 16:21








  • 3





    Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

    – NathanOliver
    Feb 15 at 16:21






  • 25





    Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

    – 0x5453
    Feb 15 at 16:21








  • 6





    Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

    – James Adkison
    Feb 15 at 16:22








  • 9





    Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

    – François Andrieux
    Feb 15 at 16:22
















  • 12





    It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

    – François Andrieux
    Feb 15 at 16:21








  • 3





    Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

    – NathanOliver
    Feb 15 at 16:21






  • 25





    Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

    – 0x5453
    Feb 15 at 16:21








  • 6





    Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

    – James Adkison
    Feb 15 at 16:22








  • 9





    Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

    – François Andrieux
    Feb 15 at 16:22










12




12





It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

– François Andrieux
Feb 15 at 16:21







It really just depends on if finding a result is an exceptional situation or not and on how you want your function to behave.

– François Andrieux
Feb 15 at 16:21






3




3





Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

– NathanOliver
Feb 15 at 16:21





Good practice,maybe. std::optional is my preferred solution if no result isn't exceptional.

– NathanOliver
Feb 15 at 16:21




25




25





Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

– 0x5453
Feb 15 at 16:21







Exceptions are for exceptional situations. So it depends on your function. If your function is always expected to return a result, then throwing would make sense. Otherwise, if "nothing found" is a valid result, then you are better off with something like std::optional.

– 0x5453
Feb 15 at 16:21






6




6





Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

– James Adkison
Feb 15 at 16:22







Is this really an exceptional case? If there was nothing to do then no results (i.e., an empty vector) conveys that. This is completely different than an internal failure that caused computing the results to fail.

– James Adkison
Feb 15 at 16:22






9




9





Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

– François Andrieux
Feb 15 at 16:22







Note that if what you are actually doing is replacing a return with a throw in the sense that you want to return a result via throw, then it's a very bad idea. This is not what you are doing here. throw is being used to signal a failure which is what it's designed for.

– François Andrieux
Feb 15 at 16:22














10 Answers
10






active

oldest

votes


















21














The concepts of this answer are taken from the C++ Programming language by Bjarne Stroustrup.



SHORT ANSWER



Yes, exception-throwing can be used as returning value method. An example is the following for a binary tree search function:



void fnd(Tree∗ p, const string& s)
{
if (s == p−>str) throw p; // found s
if (p−>left) fnd(p−>left,s);
if (p−>right) fnd(p−>right,s);
}


Tree∗ find(Tree∗ p, const string& s)
{
try {
fnd(p,s);
}
catch (Tree∗ q) {
// q->str==s
return q;
}
return 0;
}


However, it should be avoided because:




  • they allow you to separate error code from "ordinary code" making your program much more readable, comprehensible and manageable. If you use them as return method, this does not hold anymore.

  • there might be inefficiencies because exception implementations rely on the assumption that they are used as error-handling methods.


Apart from that, there are further limitations:




  • exceptions must be of copy-able type

  • exceptions can handle only synchronous events

  • they should be avoided in a time-critical system

  • they should be avoided in large old programs in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


Longer answer



An exception is an object thrown to represent the occurrence of an error. It can be of any type that can be copied but it is strongly recommended to use only user-defined types specifically defined for that purpose. Exceptions allow the programmer to explicitly separate error-handling code from "ordinary code" making the program more readable.



First of all, exceptions are for managing synchronous events, not asynchronous ones. This is one first limitation.



One might think of the exception-handling mechanisms as simply another control structure, an alternative way of returning a value to a caller.



This has some charm but should be avoided because it is likely to cause confusion and inefficiencies. Stroustrup suggests:




When at all possible stick to the "exception handling is an error
handling" view. When this is done code is separated into two categories:
ordinary code and error handling code. This makes the code more
comprehensible. Furthermore, the implementations of the exception
mechanisms are optimized based on the assumption that this simple
model underlies the use of the exception.




So basically using exceptions to return value should be avoided because





  • exception implementation is optimized assuming they are used for error-handling and not for returning values hence they might be inefficient for that;

  • They allow separating error code from ordinary code making the code much more readable and comprehensible. Anything that helps preserve a clear model of what is an error and how it is handled should be treasured.


There are programs that for practical or historical reasons cannot use exceptions (neither as error handling so even less):




  • A time-critical component of an embedded system where operation must be guaranteed to complete in a specified maximum time. In the absence of tools that can accurately estimate the maximum time for an exception to propagate from throw to catch alternative error handling methods must be used.

  • A large old program in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


In the above cases, traditional pre-exception methods are preferred.






share|improve this answer


























  • Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

    – Cole Johnson
    2 days ago











  • The question is about exception throwing as returning method. This is an example about it

    – Francesco Boi
    2 days ago



















38















In C++ functions, is it a good practice to replace return with throw?




Return is not something that can be replaced by a throw in general.



In exceptional cases where you have nothing to return, throwing an exception can be a valid way to exit the function.



Whether it is "good practice", and what case is "exceptional" are subjective. For example, for a search function such as yours, it's hardly a surprise that there might not be a solution, and I would argue that throwing would not be appropriate.



There are often other alternatives to throwing. Compare your algorithm with something like std::string::find that returns the index of the start of a substring. In case where substring does not exist, it returns a "non-value" std::string::npos. You could do the same and decide that the index -1 is returned when a result is not found. There is also a generic way to add non-value representation to a type in cases where none of the existing representations can be reserved for the purpose: std::optional.



P.S. A vector is probably not a good choice for returning a pair of numbers. std::pair might be better, or a custom class if you have good names for the numbers.






share|improve this answer





















  • 4





    Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

    – Joker_vD
    Feb 15 at 18:03











  • @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

    – eerorika
    Feb 15 at 18:09








  • 6





    @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

    – Peter Cordes
    Feb 15 at 20:45











  • This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

    – Daniel Schepler
    Feb 15 at 23:49






  • 1





    of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

    – Eevee
    Feb 16 at 8:41



















16














return and throw have two different purposes and should not be considered interchangeable. Use return when you have a valid result to send back to the caller. On the other hand, use throw when some exceptional behavior occurs. You can get an idea of how other programmers use throw by using functions from the standard library and taking note of when they throw exceptions.






share|improve this answer































    12














    In addition to the other answers, there's also performance: Catching an exception incurs a run-time overhead (see this answer) compared to an if clause.



    (Of course, we're talking about microseconds... Whether or not this is relevant depends on your specific use case.)






    share|improve this answer



















    • 7





      Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

      – Peter Cordes
      Feb 15 at 20:53



















    6














    A function should throw an exception when it is unable to meet its postcondition. (Some functions may also throw exceptions when their preconditions are not met; that's a different topic that I won't get into here.) Therefore, if your function must return a pair of integers from the vector summing to the given target, then it has no choice but to throw an exception when it can't find one. But if the function's contract allows it to return a value to indicate it was unable to find such a pair, then it should not throw an exception, since it has the ability to fulfill the contract.



    In your case:




    • You can make your function return an empty vector when it can't find two integers summing to the given target. Then, it never needs to throw an exception.

    • Or, you can make your function return std::optional<std::pair<int, int>>. It never needs to throw an exception because it can just return an empty optional when it can't find an appropriate pair.

    • If, however, you make it return std::pair<int, int>, then it should throw an exception because there is no sensible value to return when it can't find an appropriate pair.


    Generally, C++ programmers prefer to write functions that don't need to throw exceptions in order to report mere "disappointments", such as search failures, that are easily anticipated and handled locally. The advantages of returning values rather than throwing exceptions are discussed extensively elsewhere so I won't rehash that discussion here.



    Thus, declaring "failure" by throwing an exception is usually limited to the following cases:




    • The function is a constructor and it's simply not able to establish its class's invariant. It must throw an exception in order to ensure that the calling code doesn't see a broken object.

    • An "exceptional" condition arises that should be handled at some higher level than that of the caller. The caller is likely to not know how to recover from the condition. In such cases, the use of the exception mechanism frees up the caller from having to figure out how to proceed when the exceptional condition occurs.






    share|improve this answer































      5














      What you have mentioned is not good programming practice. Replacing a return statement with throw is not acceptable in production-level code, especially with automated testing platforms that generate lists of all exceptions as a way of proving or disproving certain functionality. You have to take into consideration the needs of Software Testers when designing your code. throw is simply not interchangeable with return. throw is used to signal that a program error has occurred by some unexpected phenomena. return is used to signal method completion. It is common to use return to transmit error codes, but return values do not cause the program to be interrupted in the same way as throw does. Additionally, throw has the power to terminate a program if it is not handled correctly.



      Essentially, it is good practice to use throw when a significant error is detected within the method, but there should always be a clean return if such an error is not detected. Can you make that substitution? Maybe, and maybe it will work logically...but it's not good practice and certainly not a popular implementation.






      share|improve this answer

































        4














        No, throw is not a good semantic replacement for return. You only want to use throw when your code has done something that it should not be doing, not to signify the perfectly valid negative result of a function.



        As a general rule, exceptions are meant to signify when something abnormal or unexpected has happened during the execution of your code. Looking at the purpose of your function, the occurrence of no two integers in the passed vector summing to target is a very possible result of the function, so that result is not abnormal and therefore should not be treated as exceptional.






        share|improve this answer































          2














          Just because the function is throwing as the last call, doesn't mean it is replacing return. It is just the flow of logic.



          The question shouldn't be :




          is it a good practice to replace return with throw?




          Instead it should be about how to define your API and contracts.



          If You want to guarantee to the users of the function that vector is never empty, then throwing an exception is a good idea.



          If you want to guarantee that your function doesn't throw exceptions instead returns an empty vector on certain conditions, then throwing is a bad idea.



          In both cases, the user has to know, what actions they have to take to correctly use your function.






          share|improve this answer































            1














            Your question is language agnostic.



            Return and Throw have different purposes.




            • Return is for returning a value; while,

            • Throw is for throwing an exception; and,


              • An exception should be thrown in truly exceptional conditions.






            Bonus Content (from Steve McConnell’s Code Complete 2)



            Here are all the alternatives available to you when you encounter a situation where you cannot return normally:





            • Return a neutral value like -1 from a method that’s supposed to return count of something;


            • Return the closest legal value like 0 on the digital speedometer of a car when it is going in reverse;


            • Return same value as previous call like a temperature reading on a thermometer when you are reading every second and you know that the readings do not differ drastically in such a short interval;


            • Return the next valid piece of data like when you are reading rows from a table and a specific row is corrupt;


            • Set/Return an error status/code/object found pretty commonly in C++ library calls;


            • Display a message in an alert box but be careful to not give out too much that can assist a malicious actor;


            • Log to a file;


            • Throw an exception like you are pondering upon;


            • Call a central error handler/routine if that is how your system is designed;


            • Shutdown.


            Further, you do not need to pick only one of the above options. You can do a combination like, for example, logging to file and displaying a message to the user.



            What approach you should take is a question of Correctness vs Robustness. Do you want your program to be absolutely correct and shutdown when an erroneous situation is encountered or do you want your program to be robust and continue with execution when at some point it fails to follow the desired path?






            share|improve this answer































              0














              I think it is the wrong question asking if return can be replaced by throw. return and throw are doing two very different things:





              • return is used to return regular results of a functions.


              • throw is the preferred method to react on error conditions when a result value does not exist.


              The alternative reaction on errors could be to return special error code values. This has some disadvantages, e.g.:




              • Using a function gets more difficult if you always have to keep error codes etc. in mind.

              • The caller might forget to handle the error. When you forget an exception handler, you will get unhandled exception. It is very likely that you will detect this bug.

              • The error might be too complex to be expressed by a single error code properly. An exception can be an object containing all the information you need.

              • The errors are handled at a well-defined position (the exception handler). This will make your code much clearer than checking the return value for special values after each call.


              In your example the answer depends on the semantics of the function:



              If an empty vector is an acceptable return value, then you should use return if no pair is found.



              If it is expected that there MUST be matching pairs always, then finding no pair obviously is an error. You should use throw in this case.






              share|improve this answer








              New contributor




              bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.




















                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54713231%2fusing-throw-to-replace-return-in-c-non-void-functions%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                10 Answers
                10






                active

                oldest

                votes








                10 Answers
                10






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                21














                The concepts of this answer are taken from the C++ Programming language by Bjarne Stroustrup.



                SHORT ANSWER



                Yes, exception-throwing can be used as returning value method. An example is the following for a binary tree search function:



                void fnd(Tree∗ p, const string& s)
                {
                if (s == p−>str) throw p; // found s
                if (p−>left) fnd(p−>left,s);
                if (p−>right) fnd(p−>right,s);
                }


                Tree∗ find(Tree∗ p, const string& s)
                {
                try {
                fnd(p,s);
                }
                catch (Tree∗ q) {
                // q->str==s
                return q;
                }
                return 0;
                }


                However, it should be avoided because:




                • they allow you to separate error code from "ordinary code" making your program much more readable, comprehensible and manageable. If you use them as return method, this does not hold anymore.

                • there might be inefficiencies because exception implementations rely on the assumption that they are used as error-handling methods.


                Apart from that, there are further limitations:




                • exceptions must be of copy-able type

                • exceptions can handle only synchronous events

                • they should be avoided in a time-critical system

                • they should be avoided in large old programs in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                Longer answer



                An exception is an object thrown to represent the occurrence of an error. It can be of any type that can be copied but it is strongly recommended to use only user-defined types specifically defined for that purpose. Exceptions allow the programmer to explicitly separate error-handling code from "ordinary code" making the program more readable.



                First of all, exceptions are for managing synchronous events, not asynchronous ones. This is one first limitation.



                One might think of the exception-handling mechanisms as simply another control structure, an alternative way of returning a value to a caller.



                This has some charm but should be avoided because it is likely to cause confusion and inefficiencies. Stroustrup suggests:




                When at all possible stick to the "exception handling is an error
                handling" view. When this is done code is separated into two categories:
                ordinary code and error handling code. This makes the code more
                comprehensible. Furthermore, the implementations of the exception
                mechanisms are optimized based on the assumption that this simple
                model underlies the use of the exception.




                So basically using exceptions to return value should be avoided because





                • exception implementation is optimized assuming they are used for error-handling and not for returning values hence they might be inefficient for that;

                • They allow separating error code from ordinary code making the code much more readable and comprehensible. Anything that helps preserve a clear model of what is an error and how it is handled should be treasured.


                There are programs that for practical or historical reasons cannot use exceptions (neither as error handling so even less):




                • A time-critical component of an embedded system where operation must be guaranteed to complete in a specified maximum time. In the absence of tools that can accurately estimate the maximum time for an exception to propagate from throw to catch alternative error handling methods must be used.

                • A large old program in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                In the above cases, traditional pre-exception methods are preferred.






                share|improve this answer


























                • Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                  – Cole Johnson
                  2 days ago











                • The question is about exception throwing as returning method. This is an example about it

                  – Francesco Boi
                  2 days ago
















                21














                The concepts of this answer are taken from the C++ Programming language by Bjarne Stroustrup.



                SHORT ANSWER



                Yes, exception-throwing can be used as returning value method. An example is the following for a binary tree search function:



                void fnd(Tree∗ p, const string& s)
                {
                if (s == p−>str) throw p; // found s
                if (p−>left) fnd(p−>left,s);
                if (p−>right) fnd(p−>right,s);
                }


                Tree∗ find(Tree∗ p, const string& s)
                {
                try {
                fnd(p,s);
                }
                catch (Tree∗ q) {
                // q->str==s
                return q;
                }
                return 0;
                }


                However, it should be avoided because:




                • they allow you to separate error code from "ordinary code" making your program much more readable, comprehensible and manageable. If you use them as return method, this does not hold anymore.

                • there might be inefficiencies because exception implementations rely on the assumption that they are used as error-handling methods.


                Apart from that, there are further limitations:




                • exceptions must be of copy-able type

                • exceptions can handle only synchronous events

                • they should be avoided in a time-critical system

                • they should be avoided in large old programs in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                Longer answer



                An exception is an object thrown to represent the occurrence of an error. It can be of any type that can be copied but it is strongly recommended to use only user-defined types specifically defined for that purpose. Exceptions allow the programmer to explicitly separate error-handling code from "ordinary code" making the program more readable.



                First of all, exceptions are for managing synchronous events, not asynchronous ones. This is one first limitation.



                One might think of the exception-handling mechanisms as simply another control structure, an alternative way of returning a value to a caller.



                This has some charm but should be avoided because it is likely to cause confusion and inefficiencies. Stroustrup suggests:




                When at all possible stick to the "exception handling is an error
                handling" view. When this is done code is separated into two categories:
                ordinary code and error handling code. This makes the code more
                comprehensible. Furthermore, the implementations of the exception
                mechanisms are optimized based on the assumption that this simple
                model underlies the use of the exception.




                So basically using exceptions to return value should be avoided because





                • exception implementation is optimized assuming they are used for error-handling and not for returning values hence they might be inefficient for that;

                • They allow separating error code from ordinary code making the code much more readable and comprehensible. Anything that helps preserve a clear model of what is an error and how it is handled should be treasured.


                There are programs that for practical or historical reasons cannot use exceptions (neither as error handling so even less):




                • A time-critical component of an embedded system where operation must be guaranteed to complete in a specified maximum time. In the absence of tools that can accurately estimate the maximum time for an exception to propagate from throw to catch alternative error handling methods must be used.

                • A large old program in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                In the above cases, traditional pre-exception methods are preferred.






                share|improve this answer


























                • Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                  – Cole Johnson
                  2 days ago











                • The question is about exception throwing as returning method. This is an example about it

                  – Francesco Boi
                  2 days ago














                21












                21








                21







                The concepts of this answer are taken from the C++ Programming language by Bjarne Stroustrup.



                SHORT ANSWER



                Yes, exception-throwing can be used as returning value method. An example is the following for a binary tree search function:



                void fnd(Tree∗ p, const string& s)
                {
                if (s == p−>str) throw p; // found s
                if (p−>left) fnd(p−>left,s);
                if (p−>right) fnd(p−>right,s);
                }


                Tree∗ find(Tree∗ p, const string& s)
                {
                try {
                fnd(p,s);
                }
                catch (Tree∗ q) {
                // q->str==s
                return q;
                }
                return 0;
                }


                However, it should be avoided because:




                • they allow you to separate error code from "ordinary code" making your program much more readable, comprehensible and manageable. If you use them as return method, this does not hold anymore.

                • there might be inefficiencies because exception implementations rely on the assumption that they are used as error-handling methods.


                Apart from that, there are further limitations:




                • exceptions must be of copy-able type

                • exceptions can handle only synchronous events

                • they should be avoided in a time-critical system

                • they should be avoided in large old programs in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                Longer answer



                An exception is an object thrown to represent the occurrence of an error. It can be of any type that can be copied but it is strongly recommended to use only user-defined types specifically defined for that purpose. Exceptions allow the programmer to explicitly separate error-handling code from "ordinary code" making the program more readable.



                First of all, exceptions are for managing synchronous events, not asynchronous ones. This is one first limitation.



                One might think of the exception-handling mechanisms as simply another control structure, an alternative way of returning a value to a caller.



                This has some charm but should be avoided because it is likely to cause confusion and inefficiencies. Stroustrup suggests:




                When at all possible stick to the "exception handling is an error
                handling" view. When this is done code is separated into two categories:
                ordinary code and error handling code. This makes the code more
                comprehensible. Furthermore, the implementations of the exception
                mechanisms are optimized based on the assumption that this simple
                model underlies the use of the exception.




                So basically using exceptions to return value should be avoided because





                • exception implementation is optimized assuming they are used for error-handling and not for returning values hence they might be inefficient for that;

                • They allow separating error code from ordinary code making the code much more readable and comprehensible. Anything that helps preserve a clear model of what is an error and how it is handled should be treasured.


                There are programs that for practical or historical reasons cannot use exceptions (neither as error handling so even less):




                • A time-critical component of an embedded system where operation must be guaranteed to complete in a specified maximum time. In the absence of tools that can accurately estimate the maximum time for an exception to propagate from throw to catch alternative error handling methods must be used.

                • A large old program in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                In the above cases, traditional pre-exception methods are preferred.






                share|improve this answer















                The concepts of this answer are taken from the C++ Programming language by Bjarne Stroustrup.



                SHORT ANSWER



                Yes, exception-throwing can be used as returning value method. An example is the following for a binary tree search function:



                void fnd(Tree∗ p, const string& s)
                {
                if (s == p−>str) throw p; // found s
                if (p−>left) fnd(p−>left,s);
                if (p−>right) fnd(p−>right,s);
                }


                Tree∗ find(Tree∗ p, const string& s)
                {
                try {
                fnd(p,s);
                }
                catch (Tree∗ q) {
                // q->str==s
                return q;
                }
                return 0;
                }


                However, it should be avoided because:




                • they allow you to separate error code from "ordinary code" making your program much more readable, comprehensible and manageable. If you use them as return method, this does not hold anymore.

                • there might be inefficiencies because exception implementations rely on the assumption that they are used as error-handling methods.


                Apart from that, there are further limitations:




                • exceptions must be of copy-able type

                • exceptions can handle only synchronous events

                • they should be avoided in a time-critical system

                • they should be avoided in large old programs in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                Longer answer



                An exception is an object thrown to represent the occurrence of an error. It can be of any type that can be copied but it is strongly recommended to use only user-defined types specifically defined for that purpose. Exceptions allow the programmer to explicitly separate error-handling code from "ordinary code" making the program more readable.



                First of all, exceptions are for managing synchronous events, not asynchronous ones. This is one first limitation.



                One might think of the exception-handling mechanisms as simply another control structure, an alternative way of returning a value to a caller.



                This has some charm but should be avoided because it is likely to cause confusion and inefficiencies. Stroustrup suggests:




                When at all possible stick to the "exception handling is an error
                handling" view. When this is done code is separated into two categories:
                ordinary code and error handling code. This makes the code more
                comprehensible. Furthermore, the implementations of the exception
                mechanisms are optimized based on the assumption that this simple
                model underlies the use of the exception.




                So basically using exceptions to return value should be avoided because





                • exception implementation is optimized assuming they are used for error-handling and not for returning values hence they might be inefficient for that;

                • They allow separating error code from ordinary code making the code much more readable and comprehensible. Anything that helps preserve a clear model of what is an error and how it is handled should be treasured.


                There are programs that for practical or historical reasons cannot use exceptions (neither as error handling so even less):




                • A time-critical component of an embedded system where operation must be guaranteed to complete in a specified maximum time. In the absence of tools that can accurately estimate the maximum time for an exception to propagate from throw to catch alternative error handling methods must be used.

                • A large old program in which resource management is an ad hoc mess (free store is unsystematically managed using naked pointers, news and delete) rather than relying on some systematic scheme such as resource handles (strings vectors).


                In the above cases, traditional pre-exception methods are preferred.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 19 at 7:30









                eFarzad

                576721




                576721










                answered Feb 15 at 18:05









                Francesco BoiFrancesco Boi

                2,45222342




                2,45222342













                • Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                  – Cole Johnson
                  2 days ago











                • The question is about exception throwing as returning method. This is an example about it

                  – Francesco Boi
                  2 days ago



















                • Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                  – Cole Johnson
                  2 days ago











                • The question is about exception throwing as returning method. This is an example about it

                  – Francesco Boi
                  2 days ago

















                Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                – Cole Johnson
                2 days ago





                Couldn’t you just replace your throw with a return and your calls to fnd with return fnd(...)?

                – Cole Johnson
                2 days ago













                The question is about exception throwing as returning method. This is an example about it

                – Francesco Boi
                2 days ago





                The question is about exception throwing as returning method. This is an example about it

                – Francesco Boi
                2 days ago













                38















                In C++ functions, is it a good practice to replace return with throw?




                Return is not something that can be replaced by a throw in general.



                In exceptional cases where you have nothing to return, throwing an exception can be a valid way to exit the function.



                Whether it is "good practice", and what case is "exceptional" are subjective. For example, for a search function such as yours, it's hardly a surprise that there might not be a solution, and I would argue that throwing would not be appropriate.



                There are often other alternatives to throwing. Compare your algorithm with something like std::string::find that returns the index of the start of a substring. In case where substring does not exist, it returns a "non-value" std::string::npos. You could do the same and decide that the index -1 is returned when a result is not found. There is also a generic way to add non-value representation to a type in cases where none of the existing representations can be reserved for the purpose: std::optional.



                P.S. A vector is probably not a good choice for returning a pair of numbers. std::pair might be better, or a custom class if you have good names for the numbers.






                share|improve this answer





















                • 4





                  Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                  – Joker_vD
                  Feb 15 at 18:03











                • @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                  – eerorika
                  Feb 15 at 18:09








                • 6





                  @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                  – Peter Cordes
                  Feb 15 at 20:45











                • This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                  – Daniel Schepler
                  Feb 15 at 23:49






                • 1





                  of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                  – Eevee
                  Feb 16 at 8:41
















                38















                In C++ functions, is it a good practice to replace return with throw?




                Return is not something that can be replaced by a throw in general.



                In exceptional cases where you have nothing to return, throwing an exception can be a valid way to exit the function.



                Whether it is "good practice", and what case is "exceptional" are subjective. For example, for a search function such as yours, it's hardly a surprise that there might not be a solution, and I would argue that throwing would not be appropriate.



                There are often other alternatives to throwing. Compare your algorithm with something like std::string::find that returns the index of the start of a substring. In case where substring does not exist, it returns a "non-value" std::string::npos. You could do the same and decide that the index -1 is returned when a result is not found. There is also a generic way to add non-value representation to a type in cases where none of the existing representations can be reserved for the purpose: std::optional.



                P.S. A vector is probably not a good choice for returning a pair of numbers. std::pair might be better, or a custom class if you have good names for the numbers.






                share|improve this answer





















                • 4





                  Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                  – Joker_vD
                  Feb 15 at 18:03











                • @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                  – eerorika
                  Feb 15 at 18:09








                • 6





                  @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                  – Peter Cordes
                  Feb 15 at 20:45











                • This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                  – Daniel Schepler
                  Feb 15 at 23:49






                • 1





                  of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                  – Eevee
                  Feb 16 at 8:41














                38












                38








                38








                In C++ functions, is it a good practice to replace return with throw?




                Return is not something that can be replaced by a throw in general.



                In exceptional cases where you have nothing to return, throwing an exception can be a valid way to exit the function.



                Whether it is "good practice", and what case is "exceptional" are subjective. For example, for a search function such as yours, it's hardly a surprise that there might not be a solution, and I would argue that throwing would not be appropriate.



                There are often other alternatives to throwing. Compare your algorithm with something like std::string::find that returns the index of the start of a substring. In case where substring does not exist, it returns a "non-value" std::string::npos. You could do the same and decide that the index -1 is returned when a result is not found. There is also a generic way to add non-value representation to a type in cases where none of the existing representations can be reserved for the purpose: std::optional.



                P.S. A vector is probably not a good choice for returning a pair of numbers. std::pair might be better, or a custom class if you have good names for the numbers.






                share|improve this answer
















                In C++ functions, is it a good practice to replace return with throw?




                Return is not something that can be replaced by a throw in general.



                In exceptional cases where you have nothing to return, throwing an exception can be a valid way to exit the function.



                Whether it is "good practice", and what case is "exceptional" are subjective. For example, for a search function such as yours, it's hardly a surprise that there might not be a solution, and I would argue that throwing would not be appropriate.



                There are often other alternatives to throwing. Compare your algorithm with something like std::string::find that returns the index of the start of a substring. In case where substring does not exist, it returns a "non-value" std::string::npos. You could do the same and decide that the index -1 is returned when a result is not found. There is also a generic way to add non-value representation to a type in cases where none of the existing representations can be reserved for the purpose: std::optional.



                P.S. A vector is probably not a good choice for returning a pair of numbers. std::pair might be better, or a custom class if you have good names for the numbers.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 15 at 16:37

























                answered Feb 15 at 16:24









                eerorikaeerorika

                83k661127




                83k661127








                • 4





                  Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                  – Joker_vD
                  Feb 15 at 18:03











                • @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                  – eerorika
                  Feb 15 at 18:09








                • 6





                  @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                  – Peter Cordes
                  Feb 15 at 20:45











                • This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                  – Daniel Schepler
                  Feb 15 at 23:49






                • 1





                  of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                  – Eevee
                  Feb 16 at 8:41














                • 4





                  Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                  – Joker_vD
                  Feb 15 at 18:03











                • @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                  – eerorika
                  Feb 15 at 18:09








                • 6





                  @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                  – Peter Cordes
                  Feb 15 at 20:45











                • This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                  – Daniel Schepler
                  Feb 15 at 23:49






                • 1





                  of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                  – Eevee
                  Feb 16 at 8:41








                4




                4





                Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                – Joker_vD
                Feb 15 at 18:03





                Well, I've seen a small codebase once with void functions that returned results by throwing them, and try-catch was used as a sort of pattern matching tool. Quite a bizarre design, I have to admit, but it shows how to replace return with throw in general.

                – Joker_vD
                Feb 15 at 18:03













                @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                – eerorika
                Feb 15 at 18:09







                @Joker_vD frankly, I've never seen a function whose all return paths were throws (except "not implemented" style exceptions). But I admit that it would be technically legal C++. So, I've technically lied a bit when I said that returns cannot be replaced.

                – eerorika
                Feb 15 at 18:09






                6




                6





                @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                – Peter Cordes
                Feb 15 at 20:45





                @Joker_vD: it's possible, but would perform like crap on "normal" implementations. Unless they can optimize away the throw/catch, firing up the stack-unwinding exception dispatch code (which has to go read .eh_frame metadata) is vastly more expensive than a ret instruction.

                – Peter Cordes
                Feb 15 at 20:45













                This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                – Daniel Schepler
                Feb 15 at 23:49





                This would be one of the few situations where I'd agree with using std::pair - where the two elements are more or less interchangeable. On a tangent: I disagree with a lot of the places the standard library uses std::pair - for example, think how much more readable code would be if you would write auto result = m_multiplicities.emplace(k, 1); if (!result.inserted) ++(result.location->value); as opposed to if (!result.second) ++(result.first->second);

                – Daniel Schepler
                Feb 15 at 23:49




                1




                1





                of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                – Eevee
                Feb 16 at 8:41





                of course, returning an error value like std::string::npos means the caller might completely forget to check for it and pass it along to some other code, eventually producing nonsense that's hard to trace back to the original cause. this problem is the entire reason for exceptions (or optional types).

                – Eevee
                Feb 16 at 8:41











                16














                return and throw have two different purposes and should not be considered interchangeable. Use return when you have a valid result to send back to the caller. On the other hand, use throw when some exceptional behavior occurs. You can get an idea of how other programmers use throw by using functions from the standard library and taking note of when they throw exceptions.






                share|improve this answer




























                  16














                  return and throw have two different purposes and should not be considered interchangeable. Use return when you have a valid result to send back to the caller. On the other hand, use throw when some exceptional behavior occurs. You can get an idea of how other programmers use throw by using functions from the standard library and taking note of when they throw exceptions.






                  share|improve this answer


























                    16












                    16








                    16







                    return and throw have two different purposes and should not be considered interchangeable. Use return when you have a valid result to send back to the caller. On the other hand, use throw when some exceptional behavior occurs. You can get an idea of how other programmers use throw by using functions from the standard library and taking note of when they throw exceptions.






                    share|improve this answer













                    return and throw have two different purposes and should not be considered interchangeable. Use return when you have a valid result to send back to the caller. On the other hand, use throw when some exceptional behavior occurs. You can get an idea of how other programmers use throw by using functions from the standard library and taking note of when they throw exceptions.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Feb 15 at 16:24









                    Code-ApprenticeCode-Apprentice

                    47.9k1490176




                    47.9k1490176























                        12














                        In addition to the other answers, there's also performance: Catching an exception incurs a run-time overhead (see this answer) compared to an if clause.



                        (Of course, we're talking about microseconds... Whether or not this is relevant depends on your specific use case.)






                        share|improve this answer



















                        • 7





                          Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                          – Peter Cordes
                          Feb 15 at 20:53
















                        12














                        In addition to the other answers, there's also performance: Catching an exception incurs a run-time overhead (see this answer) compared to an if clause.



                        (Of course, we're talking about microseconds... Whether or not this is relevant depends on your specific use case.)






                        share|improve this answer



















                        • 7





                          Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                          – Peter Cordes
                          Feb 15 at 20:53














                        12












                        12








                        12







                        In addition to the other answers, there's also performance: Catching an exception incurs a run-time overhead (see this answer) compared to an if clause.



                        (Of course, we're talking about microseconds... Whether or not this is relevant depends on your specific use case.)






                        share|improve this answer













                        In addition to the other answers, there's also performance: Catching an exception incurs a run-time overhead (see this answer) compared to an if clause.



                        (Of course, we're talking about microseconds... Whether or not this is relevant depends on your specific use case.)







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Feb 15 at 17:08









                        Pedro LMPedro LM

                        650310




                        650310








                        • 7





                          Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                          – Peter Cordes
                          Feb 15 at 20:53














                        • 7





                          Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                          – Peter Cordes
                          Feb 15 at 20:53








                        7




                        7





                        Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                        – Peter Cordes
                        Feb 15 at 20:53





                        Function call/ret takes about a nanosecond on a 3 to 4 GHz CPU, and can overlap with surrounding work. About 1000x slower sounds plausible. But remember, microseconds is thousands of clock cycles on modern CPUs (during which time they could have executed maybe 1 to 3 instructions per clock, or even more in high-ILP code), and ~ten times longer than even a cache miss that went all the way RAM and stalled out-of-order execution. try/catch instead of return might not optimize away even after inlining, so you will end up with far more of it than you would call/ret instructions.

                        – Peter Cordes
                        Feb 15 at 20:53











                        6














                        A function should throw an exception when it is unable to meet its postcondition. (Some functions may also throw exceptions when their preconditions are not met; that's a different topic that I won't get into here.) Therefore, if your function must return a pair of integers from the vector summing to the given target, then it has no choice but to throw an exception when it can't find one. But if the function's contract allows it to return a value to indicate it was unable to find such a pair, then it should not throw an exception, since it has the ability to fulfill the contract.



                        In your case:




                        • You can make your function return an empty vector when it can't find two integers summing to the given target. Then, it never needs to throw an exception.

                        • Or, you can make your function return std::optional<std::pair<int, int>>. It never needs to throw an exception because it can just return an empty optional when it can't find an appropriate pair.

                        • If, however, you make it return std::pair<int, int>, then it should throw an exception because there is no sensible value to return when it can't find an appropriate pair.


                        Generally, C++ programmers prefer to write functions that don't need to throw exceptions in order to report mere "disappointments", such as search failures, that are easily anticipated and handled locally. The advantages of returning values rather than throwing exceptions are discussed extensively elsewhere so I won't rehash that discussion here.



                        Thus, declaring "failure" by throwing an exception is usually limited to the following cases:




                        • The function is a constructor and it's simply not able to establish its class's invariant. It must throw an exception in order to ensure that the calling code doesn't see a broken object.

                        • An "exceptional" condition arises that should be handled at some higher level than that of the caller. The caller is likely to not know how to recover from the condition. In such cases, the use of the exception mechanism frees up the caller from having to figure out how to proceed when the exceptional condition occurs.






                        share|improve this answer




























                          6














                          A function should throw an exception when it is unable to meet its postcondition. (Some functions may also throw exceptions when their preconditions are not met; that's a different topic that I won't get into here.) Therefore, if your function must return a pair of integers from the vector summing to the given target, then it has no choice but to throw an exception when it can't find one. But if the function's contract allows it to return a value to indicate it was unable to find such a pair, then it should not throw an exception, since it has the ability to fulfill the contract.



                          In your case:




                          • You can make your function return an empty vector when it can't find two integers summing to the given target. Then, it never needs to throw an exception.

                          • Or, you can make your function return std::optional<std::pair<int, int>>. It never needs to throw an exception because it can just return an empty optional when it can't find an appropriate pair.

                          • If, however, you make it return std::pair<int, int>, then it should throw an exception because there is no sensible value to return when it can't find an appropriate pair.


                          Generally, C++ programmers prefer to write functions that don't need to throw exceptions in order to report mere "disappointments", such as search failures, that are easily anticipated and handled locally. The advantages of returning values rather than throwing exceptions are discussed extensively elsewhere so I won't rehash that discussion here.



                          Thus, declaring "failure" by throwing an exception is usually limited to the following cases:




                          • The function is a constructor and it's simply not able to establish its class's invariant. It must throw an exception in order to ensure that the calling code doesn't see a broken object.

                          • An "exceptional" condition arises that should be handled at some higher level than that of the caller. The caller is likely to not know how to recover from the condition. In such cases, the use of the exception mechanism frees up the caller from having to figure out how to proceed when the exceptional condition occurs.






                          share|improve this answer


























                            6












                            6








                            6







                            A function should throw an exception when it is unable to meet its postcondition. (Some functions may also throw exceptions when their preconditions are not met; that's a different topic that I won't get into here.) Therefore, if your function must return a pair of integers from the vector summing to the given target, then it has no choice but to throw an exception when it can't find one. But if the function's contract allows it to return a value to indicate it was unable to find such a pair, then it should not throw an exception, since it has the ability to fulfill the contract.



                            In your case:




                            • You can make your function return an empty vector when it can't find two integers summing to the given target. Then, it never needs to throw an exception.

                            • Or, you can make your function return std::optional<std::pair<int, int>>. It never needs to throw an exception because it can just return an empty optional when it can't find an appropriate pair.

                            • If, however, you make it return std::pair<int, int>, then it should throw an exception because there is no sensible value to return when it can't find an appropriate pair.


                            Generally, C++ programmers prefer to write functions that don't need to throw exceptions in order to report mere "disappointments", such as search failures, that are easily anticipated and handled locally. The advantages of returning values rather than throwing exceptions are discussed extensively elsewhere so I won't rehash that discussion here.



                            Thus, declaring "failure" by throwing an exception is usually limited to the following cases:




                            • The function is a constructor and it's simply not able to establish its class's invariant. It must throw an exception in order to ensure that the calling code doesn't see a broken object.

                            • An "exceptional" condition arises that should be handled at some higher level than that of the caller. The caller is likely to not know how to recover from the condition. In such cases, the use of the exception mechanism frees up the caller from having to figure out how to proceed when the exceptional condition occurs.






                            share|improve this answer













                            A function should throw an exception when it is unable to meet its postcondition. (Some functions may also throw exceptions when their preconditions are not met; that's a different topic that I won't get into here.) Therefore, if your function must return a pair of integers from the vector summing to the given target, then it has no choice but to throw an exception when it can't find one. But if the function's contract allows it to return a value to indicate it was unable to find such a pair, then it should not throw an exception, since it has the ability to fulfill the contract.



                            In your case:




                            • You can make your function return an empty vector when it can't find two integers summing to the given target. Then, it never needs to throw an exception.

                            • Or, you can make your function return std::optional<std::pair<int, int>>. It never needs to throw an exception because it can just return an empty optional when it can't find an appropriate pair.

                            • If, however, you make it return std::pair<int, int>, then it should throw an exception because there is no sensible value to return when it can't find an appropriate pair.


                            Generally, C++ programmers prefer to write functions that don't need to throw exceptions in order to report mere "disappointments", such as search failures, that are easily anticipated and handled locally. The advantages of returning values rather than throwing exceptions are discussed extensively elsewhere so I won't rehash that discussion here.



                            Thus, declaring "failure" by throwing an exception is usually limited to the following cases:




                            • The function is a constructor and it's simply not able to establish its class's invariant. It must throw an exception in order to ensure that the calling code doesn't see a broken object.

                            • An "exceptional" condition arises that should be handled at some higher level than that of the caller. The caller is likely to not know how to recover from the condition. In such cases, the use of the exception mechanism frees up the caller from having to figure out how to proceed when the exceptional condition occurs.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Feb 15 at 21:14









                            BrianBrian

                            65.1k796183




                            65.1k796183























                                5














                                What you have mentioned is not good programming practice. Replacing a return statement with throw is not acceptable in production-level code, especially with automated testing platforms that generate lists of all exceptions as a way of proving or disproving certain functionality. You have to take into consideration the needs of Software Testers when designing your code. throw is simply not interchangeable with return. throw is used to signal that a program error has occurred by some unexpected phenomena. return is used to signal method completion. It is common to use return to transmit error codes, but return values do not cause the program to be interrupted in the same way as throw does. Additionally, throw has the power to terminate a program if it is not handled correctly.



                                Essentially, it is good practice to use throw when a significant error is detected within the method, but there should always be a clean return if such an error is not detected. Can you make that substitution? Maybe, and maybe it will work logically...but it's not good practice and certainly not a popular implementation.






                                share|improve this answer






























                                  5














                                  What you have mentioned is not good programming practice. Replacing a return statement with throw is not acceptable in production-level code, especially with automated testing platforms that generate lists of all exceptions as a way of proving or disproving certain functionality. You have to take into consideration the needs of Software Testers when designing your code. throw is simply not interchangeable with return. throw is used to signal that a program error has occurred by some unexpected phenomena. return is used to signal method completion. It is common to use return to transmit error codes, but return values do not cause the program to be interrupted in the same way as throw does. Additionally, throw has the power to terminate a program if it is not handled correctly.



                                  Essentially, it is good practice to use throw when a significant error is detected within the method, but there should always be a clean return if such an error is not detected. Can you make that substitution? Maybe, and maybe it will work logically...but it's not good practice and certainly not a popular implementation.






                                  share|improve this answer




























                                    5












                                    5








                                    5







                                    What you have mentioned is not good programming practice. Replacing a return statement with throw is not acceptable in production-level code, especially with automated testing platforms that generate lists of all exceptions as a way of proving or disproving certain functionality. You have to take into consideration the needs of Software Testers when designing your code. throw is simply not interchangeable with return. throw is used to signal that a program error has occurred by some unexpected phenomena. return is used to signal method completion. It is common to use return to transmit error codes, but return values do not cause the program to be interrupted in the same way as throw does. Additionally, throw has the power to terminate a program if it is not handled correctly.



                                    Essentially, it is good practice to use throw when a significant error is detected within the method, but there should always be a clean return if such an error is not detected. Can you make that substitution? Maybe, and maybe it will work logically...but it's not good practice and certainly not a popular implementation.






                                    share|improve this answer















                                    What you have mentioned is not good programming practice. Replacing a return statement with throw is not acceptable in production-level code, especially with automated testing platforms that generate lists of all exceptions as a way of proving or disproving certain functionality. You have to take into consideration the needs of Software Testers when designing your code. throw is simply not interchangeable with return. throw is used to signal that a program error has occurred by some unexpected phenomena. return is used to signal method completion. It is common to use return to transmit error codes, but return values do not cause the program to be interrupted in the same way as throw does. Additionally, throw has the power to terminate a program if it is not handled correctly.



                                    Essentially, it is good practice to use throw when a significant error is detected within the method, but there should always be a clean return if such an error is not detected. Can you make that substitution? Maybe, and maybe it will work logically...but it's not good practice and certainly not a popular implementation.







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Feb 15 at 17:34









                                    Ted Lyngmo

                                    2,9672518




                                    2,9672518










                                    answered Feb 15 at 16:46









                                    armitusarmitus

                                    1497




                                    1497























                                        4














                                        No, throw is not a good semantic replacement for return. You only want to use throw when your code has done something that it should not be doing, not to signify the perfectly valid negative result of a function.



                                        As a general rule, exceptions are meant to signify when something abnormal or unexpected has happened during the execution of your code. Looking at the purpose of your function, the occurrence of no two integers in the passed vector summing to target is a very possible result of the function, so that result is not abnormal and therefore should not be treated as exceptional.






                                        share|improve this answer




























                                          4














                                          No, throw is not a good semantic replacement for return. You only want to use throw when your code has done something that it should not be doing, not to signify the perfectly valid negative result of a function.



                                          As a general rule, exceptions are meant to signify when something abnormal or unexpected has happened during the execution of your code. Looking at the purpose of your function, the occurrence of no two integers in the passed vector summing to target is a very possible result of the function, so that result is not abnormal and therefore should not be treated as exceptional.






                                          share|improve this answer


























                                            4












                                            4








                                            4







                                            No, throw is not a good semantic replacement for return. You only want to use throw when your code has done something that it should not be doing, not to signify the perfectly valid negative result of a function.



                                            As a general rule, exceptions are meant to signify when something abnormal or unexpected has happened during the execution of your code. Looking at the purpose of your function, the occurrence of no two integers in the passed vector summing to target is a very possible result of the function, so that result is not abnormal and therefore should not be treated as exceptional.






                                            share|improve this answer













                                            No, throw is not a good semantic replacement for return. You only want to use throw when your code has done something that it should not be doing, not to signify the perfectly valid negative result of a function.



                                            As a general rule, exceptions are meant to signify when something abnormal or unexpected has happened during the execution of your code. Looking at the purpose of your function, the occurrence of no two integers in the passed vector summing to target is a very possible result of the function, so that result is not abnormal and therefore should not be treated as exceptional.







                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered Feb 15 at 18:50









                                            Abion47Abion47

                                            6,51821639




                                            6,51821639























                                                2














                                                Just because the function is throwing as the last call, doesn't mean it is replacing return. It is just the flow of logic.



                                                The question shouldn't be :




                                                is it a good practice to replace return with throw?




                                                Instead it should be about how to define your API and contracts.



                                                If You want to guarantee to the users of the function that vector is never empty, then throwing an exception is a good idea.



                                                If you want to guarantee that your function doesn't throw exceptions instead returns an empty vector on certain conditions, then throwing is a bad idea.



                                                In both cases, the user has to know, what actions they have to take to correctly use your function.






                                                share|improve this answer




























                                                  2














                                                  Just because the function is throwing as the last call, doesn't mean it is replacing return. It is just the flow of logic.



                                                  The question shouldn't be :




                                                  is it a good practice to replace return with throw?




                                                  Instead it should be about how to define your API and contracts.



                                                  If You want to guarantee to the users of the function that vector is never empty, then throwing an exception is a good idea.



                                                  If you want to guarantee that your function doesn't throw exceptions instead returns an empty vector on certain conditions, then throwing is a bad idea.



                                                  In both cases, the user has to know, what actions they have to take to correctly use your function.






                                                  share|improve this answer


























                                                    2












                                                    2








                                                    2







                                                    Just because the function is throwing as the last call, doesn't mean it is replacing return. It is just the flow of logic.



                                                    The question shouldn't be :




                                                    is it a good practice to replace return with throw?




                                                    Instead it should be about how to define your API and contracts.



                                                    If You want to guarantee to the users of the function that vector is never empty, then throwing an exception is a good idea.



                                                    If you want to guarantee that your function doesn't throw exceptions instead returns an empty vector on certain conditions, then throwing is a bad idea.



                                                    In both cases, the user has to know, what actions they have to take to correctly use your function.






                                                    share|improve this answer













                                                    Just because the function is throwing as the last call, doesn't mean it is replacing return. It is just the flow of logic.



                                                    The question shouldn't be :




                                                    is it a good practice to replace return with throw?




                                                    Instead it should be about how to define your API and contracts.



                                                    If You want to guarantee to the users of the function that vector is never empty, then throwing an exception is a good idea.



                                                    If you want to guarantee that your function doesn't throw exceptions instead returns an empty vector on certain conditions, then throwing is a bad idea.



                                                    In both cases, the user has to know, what actions they have to take to correctly use your function.







                                                    share|improve this answer












                                                    share|improve this answer



                                                    share|improve this answer










                                                    answered Feb 16 at 16:42









                                                    Robert AndrzejukRobert Andrzejuk

                                                    2,95621425




                                                    2,95621425























                                                        1














                                                        Your question is language agnostic.



                                                        Return and Throw have different purposes.




                                                        • Return is for returning a value; while,

                                                        • Throw is for throwing an exception; and,


                                                          • An exception should be thrown in truly exceptional conditions.






                                                        Bonus Content (from Steve McConnell’s Code Complete 2)



                                                        Here are all the alternatives available to you when you encounter a situation where you cannot return normally:





                                                        • Return a neutral value like -1 from a method that’s supposed to return count of something;


                                                        • Return the closest legal value like 0 on the digital speedometer of a car when it is going in reverse;


                                                        • Return same value as previous call like a temperature reading on a thermometer when you are reading every second and you know that the readings do not differ drastically in such a short interval;


                                                        • Return the next valid piece of data like when you are reading rows from a table and a specific row is corrupt;


                                                        • Set/Return an error status/code/object found pretty commonly in C++ library calls;


                                                        • Display a message in an alert box but be careful to not give out too much that can assist a malicious actor;


                                                        • Log to a file;


                                                        • Throw an exception like you are pondering upon;


                                                        • Call a central error handler/routine if that is how your system is designed;


                                                        • Shutdown.


                                                        Further, you do not need to pick only one of the above options. You can do a combination like, for example, logging to file and displaying a message to the user.



                                                        What approach you should take is a question of Correctness vs Robustness. Do you want your program to be absolutely correct and shutdown when an erroneous situation is encountered or do you want your program to be robust and continue with execution when at some point it fails to follow the desired path?






                                                        share|improve this answer




























                                                          1














                                                          Your question is language agnostic.



                                                          Return and Throw have different purposes.




                                                          • Return is for returning a value; while,

                                                          • Throw is for throwing an exception; and,


                                                            • An exception should be thrown in truly exceptional conditions.






                                                          Bonus Content (from Steve McConnell’s Code Complete 2)



                                                          Here are all the alternatives available to you when you encounter a situation where you cannot return normally:





                                                          • Return a neutral value like -1 from a method that’s supposed to return count of something;


                                                          • Return the closest legal value like 0 on the digital speedometer of a car when it is going in reverse;


                                                          • Return same value as previous call like a temperature reading on a thermometer when you are reading every second and you know that the readings do not differ drastically in such a short interval;


                                                          • Return the next valid piece of data like when you are reading rows from a table and a specific row is corrupt;


                                                          • Set/Return an error status/code/object found pretty commonly in C++ library calls;


                                                          • Display a message in an alert box but be careful to not give out too much that can assist a malicious actor;


                                                          • Log to a file;


                                                          • Throw an exception like you are pondering upon;


                                                          • Call a central error handler/routine if that is how your system is designed;


                                                          • Shutdown.


                                                          Further, you do not need to pick only one of the above options. You can do a combination like, for example, logging to file and displaying a message to the user.



                                                          What approach you should take is a question of Correctness vs Robustness. Do you want your program to be absolutely correct and shutdown when an erroneous situation is encountered or do you want your program to be robust and continue with execution when at some point it fails to follow the desired path?






                                                          share|improve this answer


























                                                            1












                                                            1








                                                            1







                                                            Your question is language agnostic.



                                                            Return and Throw have different purposes.




                                                            • Return is for returning a value; while,

                                                            • Throw is for throwing an exception; and,


                                                              • An exception should be thrown in truly exceptional conditions.






                                                            Bonus Content (from Steve McConnell’s Code Complete 2)



                                                            Here are all the alternatives available to you when you encounter a situation where you cannot return normally:





                                                            • Return a neutral value like -1 from a method that’s supposed to return count of something;


                                                            • Return the closest legal value like 0 on the digital speedometer of a car when it is going in reverse;


                                                            • Return same value as previous call like a temperature reading on a thermometer when you are reading every second and you know that the readings do not differ drastically in such a short interval;


                                                            • Return the next valid piece of data like when you are reading rows from a table and a specific row is corrupt;


                                                            • Set/Return an error status/code/object found pretty commonly in C++ library calls;


                                                            • Display a message in an alert box but be careful to not give out too much that can assist a malicious actor;


                                                            • Log to a file;


                                                            • Throw an exception like you are pondering upon;


                                                            • Call a central error handler/routine if that is how your system is designed;


                                                            • Shutdown.


                                                            Further, you do not need to pick only one of the above options. You can do a combination like, for example, logging to file and displaying a message to the user.



                                                            What approach you should take is a question of Correctness vs Robustness. Do you want your program to be absolutely correct and shutdown when an erroneous situation is encountered or do you want your program to be robust and continue with execution when at some point it fails to follow the desired path?






                                                            share|improve this answer













                                                            Your question is language agnostic.



                                                            Return and Throw have different purposes.




                                                            • Return is for returning a value; while,

                                                            • Throw is for throwing an exception; and,


                                                              • An exception should be thrown in truly exceptional conditions.






                                                            Bonus Content (from Steve McConnell’s Code Complete 2)



                                                            Here are all the alternatives available to you when you encounter a situation where you cannot return normally:





                                                            • Return a neutral value like -1 from a method that’s supposed to return count of something;


                                                            • Return the closest legal value like 0 on the digital speedometer of a car when it is going in reverse;


                                                            • Return same value as previous call like a temperature reading on a thermometer when you are reading every second and you know that the readings do not differ drastically in such a short interval;


                                                            • Return the next valid piece of data like when you are reading rows from a table and a specific row is corrupt;


                                                            • Set/Return an error status/code/object found pretty commonly in C++ library calls;


                                                            • Display a message in an alert box but be careful to not give out too much that can assist a malicious actor;


                                                            • Log to a file;


                                                            • Throw an exception like you are pondering upon;


                                                            • Call a central error handler/routine if that is how your system is designed;


                                                            • Shutdown.


                                                            Further, you do not need to pick only one of the above options. You can do a combination like, for example, logging to file and displaying a message to the user.



                                                            What approach you should take is a question of Correctness vs Robustness. Do you want your program to be absolutely correct and shutdown when an erroneous situation is encountered or do you want your program to be robust and continue with execution when at some point it fails to follow the desired path?







                                                            share|improve this answer












                                                            share|improve this answer



                                                            share|improve this answer










                                                            answered Feb 16 at 5:16









                                                            displayNamedisplayName

                                                            8,97333556




                                                            8,97333556























                                                                0














                                                                I think it is the wrong question asking if return can be replaced by throw. return and throw are doing two very different things:





                                                                • return is used to return regular results of a functions.


                                                                • throw is the preferred method to react on error conditions when a result value does not exist.


                                                                The alternative reaction on errors could be to return special error code values. This has some disadvantages, e.g.:




                                                                • Using a function gets more difficult if you always have to keep error codes etc. in mind.

                                                                • The caller might forget to handle the error. When you forget an exception handler, you will get unhandled exception. It is very likely that you will detect this bug.

                                                                • The error might be too complex to be expressed by a single error code properly. An exception can be an object containing all the information you need.

                                                                • The errors are handled at a well-defined position (the exception handler). This will make your code much clearer than checking the return value for special values after each call.


                                                                In your example the answer depends on the semantics of the function:



                                                                If an empty vector is an acceptable return value, then you should use return if no pair is found.



                                                                If it is expected that there MUST be matching pairs always, then finding no pair obviously is an error. You should use throw in this case.






                                                                share|improve this answer








                                                                New contributor




                                                                bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                Check out our Code of Conduct.

























                                                                  0














                                                                  I think it is the wrong question asking if return can be replaced by throw. return and throw are doing two very different things:





                                                                  • return is used to return regular results of a functions.


                                                                  • throw is the preferred method to react on error conditions when a result value does not exist.


                                                                  The alternative reaction on errors could be to return special error code values. This has some disadvantages, e.g.:




                                                                  • Using a function gets more difficult if you always have to keep error codes etc. in mind.

                                                                  • The caller might forget to handle the error. When you forget an exception handler, you will get unhandled exception. It is very likely that you will detect this bug.

                                                                  • The error might be too complex to be expressed by a single error code properly. An exception can be an object containing all the information you need.

                                                                  • The errors are handled at a well-defined position (the exception handler). This will make your code much clearer than checking the return value for special values after each call.


                                                                  In your example the answer depends on the semantics of the function:



                                                                  If an empty vector is an acceptable return value, then you should use return if no pair is found.



                                                                  If it is expected that there MUST be matching pairs always, then finding no pair obviously is an error. You should use throw in this case.






                                                                  share|improve this answer








                                                                  New contributor




                                                                  bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                  Check out our Code of Conduct.























                                                                    0












                                                                    0








                                                                    0







                                                                    I think it is the wrong question asking if return can be replaced by throw. return and throw are doing two very different things:





                                                                    • return is used to return regular results of a functions.


                                                                    • throw is the preferred method to react on error conditions when a result value does not exist.


                                                                    The alternative reaction on errors could be to return special error code values. This has some disadvantages, e.g.:




                                                                    • Using a function gets more difficult if you always have to keep error codes etc. in mind.

                                                                    • The caller might forget to handle the error. When you forget an exception handler, you will get unhandled exception. It is very likely that you will detect this bug.

                                                                    • The error might be too complex to be expressed by a single error code properly. An exception can be an object containing all the information you need.

                                                                    • The errors are handled at a well-defined position (the exception handler). This will make your code much clearer than checking the return value for special values after each call.


                                                                    In your example the answer depends on the semantics of the function:



                                                                    If an empty vector is an acceptable return value, then you should use return if no pair is found.



                                                                    If it is expected that there MUST be matching pairs always, then finding no pair obviously is an error. You should use throw in this case.






                                                                    share|improve this answer








                                                                    New contributor




                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.










                                                                    I think it is the wrong question asking if return can be replaced by throw. return and throw are doing two very different things:





                                                                    • return is used to return regular results of a functions.


                                                                    • throw is the preferred method to react on error conditions when a result value does not exist.


                                                                    The alternative reaction on errors could be to return special error code values. This has some disadvantages, e.g.:




                                                                    • Using a function gets more difficult if you always have to keep error codes etc. in mind.

                                                                    • The caller might forget to handle the error. When you forget an exception handler, you will get unhandled exception. It is very likely that you will detect this bug.

                                                                    • The error might be too complex to be expressed by a single error code properly. An exception can be an object containing all the information you need.

                                                                    • The errors are handled at a well-defined position (the exception handler). This will make your code much clearer than checking the return value for special values after each call.


                                                                    In your example the answer depends on the semantics of the function:



                                                                    If an empty vector is an acceptable return value, then you should use return if no pair is found.



                                                                    If it is expected that there MUST be matching pairs always, then finding no pair obviously is an error. You should use throw in this case.







                                                                    share|improve this answer








                                                                    New contributor




                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.









                                                                    share|improve this answer



                                                                    share|improve this answer






                                                                    New contributor




                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.









                                                                    answered 20 hours ago









                                                                    berniebernie

                                                                    11




                                                                    11




                                                                    New contributor




                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.





                                                                    New contributor





                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.






                                                                    bernie is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                                                    Check out our Code of Conduct.






























                                                                        draft saved

                                                                        draft discarded




















































                                                                        Thanks for contributing an answer to Stack Overflow!


                                                                        • Please be sure to answer the question. Provide details and share your research!

                                                                        But avoid



                                                                        • Asking for help, clarification, or responding to other answers.

                                                                        • Making statements based on opinion; back them up with references or personal experience.


                                                                        To learn more, see our tips on writing great answers.




                                                                        draft saved


                                                                        draft discarded














                                                                        StackExchange.ready(
                                                                        function () {
                                                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54713231%2fusing-throw-to-replace-return-in-c-non-void-functions%23new-answer', 'question_page');
                                                                        }
                                                                        );

                                                                        Post as a guest















                                                                        Required, but never shown





















































                                                                        Required, but never shown














                                                                        Required, but never shown












                                                                        Required, but never shown







                                                                        Required, but never shown

































                                                                        Required, but never shown














                                                                        Required, but never shown












                                                                        Required, but never shown







                                                                        Required, but never shown







                                                                        Popular posts from this blog

                                                                        How to change which sound is reproduced for terminal bell?

                                                                        Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

                                                                        Can I use Tabulator js library in my java Spring + Thymeleaf project?