0

I'm working on a Boolean function in C/C++ that verifies multiple conditions (that are Boolean functions themselves) and only returns true if all of them are true.

Time ago I started using Guard Clauses instead of nested ifs, even though it required having multiple returns like follows:

bool foo(){
 //some initialization

 if( !condition_1() ){
  return false;
 }

 if( !condition_2() ){
  return false;
 }

 ...

 if( !condition_n() ){
  return false;
 }

 return true;
}

But now I'm asking my self if is it a good alternative to use only one return with Boolean logic, for example:

bool foo(){
 //some initialization
 return condition_1() && condition_2() && ... && condition_n() ;
}

I don't have any code to run after the guards and there are only a few of them, so the return statement is not that crowded and the code is not difficult to read. The idea is to avoid nested ifs and use only one exit point in my function.

I tested the code and it works fine, even if condition_1() makes some changes in condition_2(). So I understand that the guard clause code and this version are equivalent and the execution order is maintained form left to right. Is that correct? Are there any hidden differences that make the two versions not 100% equivalent?

Thanks!

Nedo
  • 121
  • 1
  • 11
  • 2
    I'd say the concise form is more readable. It is precisely equivalent to the long form effectively. – L. F. Jul 25 '19 at 10:44
  • 3
    Both are technically correct. I think it's quite opinion-based which one is better. I always use guards because I find them more readable. – pptaszni Jul 25 '19 at 10:44
  • 1
    No, as I said there's nothing more after the guard clauses. If that was the case I wouldn't be using the proposed method. The `...` Just represents more _if_s. – Nedo Jul 25 '19 at 10:53
  • 1
    Both options are equivalent. Which one is better is opinion-based, which is off-topic here. – Max Langhof Jul 25 '19 at 10:57
  • @MaxLanghof But there are also the questions, if the versions are really absolutely equivalent and if it might be a potential cause of errors, which I consider on-topic. – Ctx Jul 25 '19 at 11:48
  • @Ctx Then that should be the only question. As of now there are only two sentences ending with a question mark, and both those questions are opinion-based (three if you include the title). If the answers are supposed to discuss the assertion that the two versions are equivalent, the question has to be changed to reflect that. And yes, I'm aware that you can construct examples where the two versions are different (e.g. by returning `bool`-convertible objects from the conditions whose destructors have side effects affecting the following conditions), but that is extremely pathological. – Max Langhof Jul 25 '19 at 11:52
  • @Ctx And to be clear, "can it be a potential cause of errors" is not something I would consider on-topic for this case either. – Max Langhof Jul 25 '19 at 11:55
  • @MaxLanghof You are nitpicking here. To ask, if something is a "good alternative" or "best practice" are not necessarily signal words for "primarily opinion based". Someone might come up with objective reasons to disregard one or the other variant. – Ctx Jul 25 '19 at 11:55
  • @Ctx By that logic we cannot close anything as opinion-based. "The lines may be come too long" is an objective reason, just like "the function body might have too many lines to fit on screen". Weighing these tradeoffs is still a matter of opinion. Again, if the question is "are these options exactly equivalent" then we can give objective answers. But whether one or the other is more or less likely to lead to one type of error or another is simply not a suitable question for SO. – Max Langhof Jul 25 '19 at 11:59
  • @MaxLanghof If you reverse the logic, you could close _everything_ as opinion based. So, it seems like it is primarily opinion based what is primarily opinion based. – Ctx Jul 25 '19 at 12:13
  • @Ctx _"If you reverse the logic, you could close everything as opinion based."_ What logic do you want to reverse? "If not X then not Y" does not imply "If X then Y" - that is a classical fallacy. I would like to point to the existence of https://codereview.stackexchange.com which specializes in exactly these kinds of questions. And look at the answers so far: We already have a claim of "best practice" that is anything but objective. This is _exactly_ why such questions are off-topic here. – Max Langhof Jul 25 '19 at 12:24
  • @MaxLanghof Well, I do not consider these questions as "primarily opinion based" and you cannot prove, that they are (because there usually cannot be a proof). You can just _claim_, that they are and others might agree or might not. This is what I meant before. – Ctx Jul 25 '19 at 12:29
  • @Ctx And that's why the voting system is in place and why I am listing my thoughts here. Now that there are existing answers it is too late to change the scope of the question and it will soon be closed. And yes, I had to correct the link. – Max Langhof Jul 25 '19 at 12:31
  • 1
    There is nothing to choose. If the conditions are trivial, then the concise form is clearer. If the conditions are complex, or they need commentry, then the long form is clearer. Both are legal, and should produce the same code for the same conditions. – Gem Taylor Jul 25 '19 at 12:35
  • Well, I rephrased the initial question to make it more concise. I wanted to understand if the two structures have an equivalent behaviour. Additionally I wanted to know if the there was any recommendation for using or not the second proposal. – Nedo Jul 25 '19 at 13:44
  • @MaxLanghof Is there anything else I can add to improve the question and open it back? – Nedo Jul 28 '19 at 14:07
  • @Nedo Generally it is not good to change the main focus of the question after answers have been added because those answers then become invalid. Anyway, I have voted to reopen, but since I doubt enough people will revisit this question for that to lead to success, asking a new question (referencing this one) might be better if you are looking for more answers. – Max Langhof Jul 29 '19 at 07:35

2 Answers2

3

You new approach is good, depending if you want to do more than just concat bool operations, it could be useful for maintenance and readability to use a local.

bool foo(){
 //some initialization
 bool returnCondition = condition_1() &&
                        condition_2() && 
                        condition_3() && 
                        .... && 
                        condition_n();

 return returnCondition;
}

By the way, there is nothing such as the best option. Indeed, if your objective is code obfuscation, your first option is better than the 2nd.

Guillaume D
  • 2,202
  • 2
  • 10
  • 37
1

Technically the two methods you use are correct in case of the functions condition_n() is used only for checking.

But if you need to change something inside them based on a condition of something it will be a problem.

The Best Practice for writing a function body is as follows:

  • define the default return value
  • some processing
  • return the result

Let's rewrite the above function :

bool foo(){
//some initialization
  bool ret = true;

  if(condition_1() == false){
     ret = false;
  }
  else if(condition_2() == false){
     ret = false;
  }

  ...

  else if(condition_n() == false){
     ret = false;
  }

 return ret;
}
Ahmed Yasen
  • 145
  • 2
  • 13
  • 3
    wrong. condtion_N+1() is called even if condition_N() is false. it would work only with a if else-if statement. – Guillaume D Jul 25 '19 at 12:20
  • 1
    Please source your claim that this is the best practice for how to write a function body. – Max Langhof Jul 25 '19 at 12:25
  • 2
    I don't see how this would be "best practice". Doesn't look like idiomatic C or C++ to me, rather it is unnecessarily verbose and obfuscates the very simple intent by dogmatically following some arbitrary rules (that, I suspect, are intended as a guideline for more complicated cases). – Arkku Jul 25 '19 at 13:38