C++ - Avoiding multiple if statements for managing errors [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Simple question.
I have this code in front of me:
if ( somethings() == false ) {
log("error when ...somethings()");
return false;
}
// do somethings
if ( somethings2() == false ) {
log("error when ...somethings2()");
return false;
}
// ...
// eventually
if ( somethingsN() == false ) {
log("error when ...somethingsN()");
delete myData;
return false;
}
Not sexy, right ? What would be the best method(/pattern ?) for improving this code ?
Solution 1:
I was wondering about using exceptions
try {
if ( somethings() == false )
throw std::runtime_error("error when ...somethings()");
// do somethings
if ( somethings2() == false )
throw std::runtime_error("error when ...somethings2()");
// ...
if ( somethingsN() == false )
throw std::runtime_error("error when ...somethingsN()");
}
catch ( std::exception& e ) {
log(e.what());
delete myData;
return false;
}
Solution 2:
Using nested if statements
if ( somethings() ) {
// do somethings...
if ( somethings1() ) {
// ... (eventually too many indent)
if ( somethingsN() ) {
return true;
}
}
}
delete myData;
return false;
What are your methods ?
I just want to improve my coding style here.
Note (edit)
"Do not use 'delete', use smart pointers instead such as unique_ptr" (thanks all)

Throw an exception on error rather than returning a magic value for the caller to check; avoid dynamic allocation except when you really need it; use smart pointers or other RAII types to manage it when you really do. Then the code becomes rather more straightforward:
somethings();
somethings2();
// ...
somethingsN();

#define CHECK(x) \
do { if (!(x)) throw MyException(#x, __FILE__, __LINE__); } while(0)
try {
// call third-party or
// C functions that don't throw
CHECK(thisone());
CHECK(thatone());
CHECK(theotherone());
// call my own functions
anotherone(); // throws
yetanotherone(); // throws
} catch (std::exception& e) {
log(e.what());
}
And of course no delete. unique_ptr is your friend.

Related

Using single else statement for multiple if conditions [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am coding for an arduino project and i came across this problem, can anyone help me out!
if(condition1){
//my codes here
}
if(condition2){
//my codes here
}
if(condition3){
//my codes here
}
......
if(condition100){
//my codes here
}
else{
my codes here
}
I want to check all my if conditions, and execute the codes if the conditions are true, and run the else statement only if none of the if condition become true.
Note that i cant use else if because i want to check all the if conditions, and if none are true i want to run the else
If conditions are not dependent on each other
You can use a Boolean flag which is set in any of your ifs.
bool noPathTaken = true;
if ( condition1 ) {
noPathTaken = false;
// ...
}
if ( condition2 ) {
noPathTaken = false;
// ...
}
// ...
if ( noPathTaken ) { // this would be your "else"
// ...
}
must set off all else flag in each test
bool elseFlag = 1;
if(condition1){
elseFlag = 0;
my codes here
}
if(condition2){
elseFlag = 0;
my codes here
}
if(condition3){
elseFlag = 0;
my codes here
}
......
if(condition100){
elseFlag = 0;
my codes here
}
if (elseFlag) {
my codes here
}
because else gets binded only into preceding test operation, here if(condition100) {

SEH Eceptions - generating and handling [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I want to generate and handle exceptions (SEH).
How can I write a code that will lead to an "illegal instruction"-exception?
You can do something like this:
#include <Windows.h>
#include <cstdio>
::DWORD FilterFunction(::DWORD const _exception_code)
{
if(EXCEPTION_ILLEGAL_INSTRUCTION == _exception_code)
{
::std::printf("filtered\n");
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
::std::printf("not filtered\n");
return EXCEPTION_CONTINUE_SEARCH;
}
}
int main()
{
__try
{
::std::printf("trying...\n");
::RaiseException
(
EXCEPTION_ILLEGAL_INSTRUCTION // exception id
, 0 // continuable exception
, 0 // args count
, nullptr // args
); // no arguments
::std::printf("finished trying\n");
}
__except(FilterFunction(GetExceptionCode()))
{
::std::printf("exception handled\n");
}
return 0;
}
trying...
filtered
exception handled
You can raise a structured exception in Windows with:
RaiseException(EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_NONCONTINUABLE, 0, nullptr);
Reference:
https://msdn.microsoft.com/en-us/library/ms680552%28VS.85%29.aspx

How can I handle exception in catch block in c++ [duplicate]

This question already has answers here:
Nested try...catch inside C++ exception handler?
(2 answers)
Closed 1 year ago.
say I have code
try
{
....
}
catch()
{
.... // exception occur here ... how to handled.
}
Is there any mechanism in c++ by which the above scenario can be handled.
If you think this is what you really want, you can do it like this:
try
{
try
{
//...
}
catch( ... )
{
//...
if( .. )
throw std::runtime_exception( "error occured" );
}
}
catch( std::runtime_exception& e )
{
// handle exception of exception handler
}

Elegant way to perform multiple dependent error checks in C++ without goto, and without early return? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Let's say I want to call four functions consecutively, which operate on some object of mine. If any of them fails, I want to return FAILURE without calling the others, and I want to return SUCCESS iff all of them completed successfully.
Normally, I would do something like this:
if(function_zero(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_one(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_two(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_three(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
return SUCCESS;
Or, if I needed to do some cleanup:
if(function_zero(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_one(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_two(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_three(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
cleanup:
// necessary cleanup here
return status;
However, the project I am working on has some restrictions:
No goto, ever
No early return (one return per function)
Line length limit
(EDIT) No exceptions.
(EDIT) No templates.
This leads me to something like this:
if(function_zero(&myMutableObject) == SUCCESS)
{
if(function_one(&myMutableObject) == SUCCESS)
{
if(function_two(&myMutableObject) == SUCCESS)
{
status = function_three(&myMutableObject);
}
else
{
status = FAILURE;
}
}
else
{
status = FAILURE;
}
}
else
{
status = FAILURE;
}
return status;
Unfortunately, this pushes me up against the line length limit often.
My question to you is: Is there a simpler way of writing this?
Notes & Restrictions:
I must implement this logic within the code block implied here. I cannot create new functions, refactor or change the overall architecture.
(EDIT) In reality the functions have very different signatures.
Use exceptions and RAII. These are literally the problems they were invented to solve. Exceptions though are more of a system-wide feature, rather than something you can apply locally.
For the cleanup block, RAII is exactly the feature you need.
For the success/failure, we can use lambdas and variadics to chain them together implicitly.
Now we can simply write them as lambdas in the list.
status f() {
struct nested {
static template<typename F> status_t Check(F f) {
return f();
}
static template<typename F, typename... Chain> status_t Check(F f, Chain... chain) {
auto status = f();
return status != failure ? Check(chain...) : status;
}
};
return nested::Check(
[] { return function_zero(&myMutableObject); },
[] { return function_one(&myMutableObject); },
[] { return function_two(&myMutableObject); },
[] { return function_three(&myMutableObject); },
);
}
This becomes slightly more problematic if you need to capture the return value, but since it seems to be always an error code with out parameter, it should be fine if you simply declare the receiving variable in f(), then all the future lambdas can refer to it. It also does not require that every function has the same signature, or allocating various data structures.
Only call the tests if status is currently set to SUCCESS using an && operator. If it is set to FAILURE the && will fail immediately and the subsequent tests will not be executed.
status = SUCCESS
if (status == SUCCESS && function_zero(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_one(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_two(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_three(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
return status;
As #Mooing Duck suggested, you could simply do it all in an else if chain:
status = SUCCESS
if (function_zero(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_one(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_two(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_three(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
return status;
A pattern that I used several times when dealing with a long chain of C calls (typically WinAPIs) goes like this:
bool ret =
function_zero(&myMutableObject) == SUCCESS
&&
function_one(&myMutableObject) == SUCCESS
&&
function_two(&myMutableObject) == SUCCESS
&&
function_three(&myMutableObject) == SUCCESS;
if(!ret)
{
// cleanup
}
return ret?SUCCESS:FAILURE;
You may even leave the && at the end of each line, so that it looks more like a "normal" sequence of calls (although personally I like them better this way, it's clearer what's going on).
The && operator guarantees execution in the right order and only if the previous calls succeeded, and introduces the necessary sequence points (or however they are called in C++11) between the calls, so the order of evaluation of parameters between the various calls is well defined. Also, it has low enough priority not to require additional parentheses.
If you are not afraid of using COM-style macros, you can also encapsulate the == SUCCESS check in a macro, like
// in some header, maybe with a less abused name
#define OK(x) ((x) == SUCCESS)
bool ret =
OK(function_zero(&myMutableObject))
&&
OK(function_one(&myMutableObject))
&&
OK(function_two(&myMutableObject))
&&
OK(function_three(&myMutableObject));
// ...
Even better, if SUCCESS != 0 and FAILURE == 0 you can drop the OK() and == SUCCESS altogether and just use && to link the calls.
You say no exceptions, but I think you ought to know what you're giving up with that.
If you use RAII based cleanup and report errors as exceptions rather than codes, then you get code that looks like this:
function_zero(&myMutableObject);
function_one(&myMutableObject);
function_two(&myMutableObject);
function_three(&myMutableObject);
Here's a site that explains correct C++ exception handling and the benefits:
http://exceptionsafecode.com/
Some of the benefits are:
easier to read
easier to understand and maintain
wrong code looks wrong
easier to write
improved performance on the success path
'zero-cost' exceptions
compiler understands exceptions as a language feature, knows which path is the success path and which is the failure path
code size increase for exception tables is offset by elimination of error checking code
Furthermore, Herb Sutter has this to say on the subject of 'single exit' (the common name for your "No early return" rule):
In general, note that SE/SE is an obsolete idea and has always been
wrong. “Single entry,” or the idea that functions should always be
entered in one place (at their start) and not with goto jumps from the
caller’s code directly to random places inside the function body, was
and is an immensely valuable advance in computer science. It’s what
made libraries possible, because it meant you could package up a
function and reuse it and the function would always know its starting
state, where it begins, regardless of the calling code. “Single exit,”
on the other hand, got unfairly popular on the basis of optimization
(‘if there’s a single return the compiler can perform return value
optimization better’—see counterexample above) and symmetry (‘if
single entry is good, single exit must be good too’) but that is wrong
because the reasons don’t hold in reverse—allowing a caller to jump in
is bad because it’s not under the function’s control, but allowing the
function itself to return early when it knows it’s done is perfectly
fine and fully under the function’s control.
http://herbsutter.com/category/c/gotw/page/4/
You should try to get the rules updated, even if that's only possible for new projects.
You could store the function pointers in a containers of std::function (as long as they have the same signature as in the example):
std::vector<std::function<error_code (myobject&)> functions { func1, func2, func3, func4 };
error_code status = SUCCESS;
for (const auto& f : functions) {
if (f(myobject) == ERROR) {
clean_up();
status = ERROR;
break;
}
}
return status;
This could work:
bool success = true;
success = success && function_zero(&myMutableObject) != FAILURE;
success = success && function_one(&myMutableObject) != FAILURE;
success = success && function_two(&myMutableObject) != FAILURE;
success = success && function_three(&myMutableObject) != FAILURE;
return success ? SUCCESS : FAILURE;
return can be replaced to:
int status = SUCCESS;
if( !success ) status = FAILURE;
return status;
if in your company conditional operator is prohibited as well.
You might write a simple local functor:
bool fn0(int&) { return false; }
bool fn1(int&) { return false; }
bool fn2(int&) { return false; }
int main() {
struct Test {
const bool result;
typedef bool (*function)(int&);
Test(function f, int& value)
: result(f(value))
{};
operator bool () const { return result; }
};
int value;
return Test(fn0, value)
&& Test(fn1, value)
&& Test(fn2, value);
}

what's the benefit of the code [duplicate]

This question already has answers here:
In ArrayBlockingQueue, why copy final member field into local final variable?
(2 answers)
Closed 9 years ago.
While reading the source code of ArrayBlockingQueue, I found below code:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}
why not use the code
public E take() throws InterruptedException {
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}
what's the Benefit of the line code :final ReentrantLock lock = this.lock;
This idea was popularized by Doug Lea - I think that the original idea was that the JVM could possibly perform some performance related optimization when there was a final local variable used.
Check out this thread from the OpenJDK thread which discusses this very question
Edit:
A little research threw up these two related questions on stack:
In ArrayBlockingQueue, why copy final member field into local final variable?
Java Lock variable assignment before use. Why?