Yes and no - if the return is not spotted, then the else is not redundant. I also like to allow line-comment/insert to be as safe as possible, and the logic to be Column-scan-able, and not other keyword dependent.
So if (SocialSecurityNumber !=3D 0) // return else if (sex =3D=3D MALE) .... keeps the Logic flow, whilst removing the else is wholly dependent on the return.
There are other reasons why 'one exit point' is a good rule (...of thumb). One is that multiple exit points lead to maintenance problems. They are often hard to spot when reading real world code. If new code that always has to be executed, is added later, it is easy to overlook that a premature exit might prevent it from happening.
The sensibility of the 'one entry point' rule should need no explanation.
-- Chris Burrows CFB Software Astrobe: ARM Oberon-07 Development System
The implication of what you write here is that it's okay to modify functions that you have barely skimmed, because you know they will always run to the end.
You must read and understand functions and their flow of control before you modify them. A coding style that makes it easier to read and understand the functions therefore makes maintenance easier. So if multiple returns makes the code clearer, it's a good thing.
As an example, consider the very common template:
void foo(int *p) { if (!p) return; ... do something with *p }
That is clearer than:
void foo(int *p) { if (p) { ... do something with *p } }
The first version removes an extra layer of block indents, making the function slightly flatter and slightly clearer.
If someone is reading the code, and don't "spot" the return, then they haven't read the code! Do you write special code sequences just in case someone doesn't spot the "!" in "!=", or perhaps fails to see other parts of the code?
The "else" in your code is not /redundant/ as such - it is worse than that. It implies that whoever wrote the code is not sure how the control flow works in the function, and it leaves a maintainer unsure of what to change because they will think that they have misunderstood something.
Commenting out lines is not, in general, safe - you have to know what you can disable. There is no way to write code that you can arbitrarily comment out, so why are you making a special case here? There are certainly times when I write code with a view to adding or removing comments - that's part of development work. But I don't write other code in convoluted or artificial ways just in case.
Hehe - yes, they have scanned the control flow, and UNLESS they _know_ there is a return lurking somewhere they now only THINK they understand the code.
By using the flow explicit structure, we do not have to _hope_ someone spots the return.
In most cases, the return will be FAR less obvious, than this trivial example.
ie I prefer to err towards the use return for fast exits, as needed, but AVOID relying on it for actual flow control when there is no need to, as that is courting future problems.
Usually, I clearly mark such early-exit points as well.
If nothing else, I think we agree here that the most important thing is to make the code readable. If returns in the middle of the function help that, they are a good thing - if not, then they are bad.
Not at all. It is an observation that humans are fallible and it is easy to overlook a single word (return) buried in many lines of code. At least in my language of choice (Oberon) RETURN is always capitalised so it stands out from the crowd.
I disagree. The fact that the second version is not flatter is a clear indication that the body is conditionally executed. If that were not true you could just make it flatter by removing all indentation!
The ability to spot an exit point is a different issue than having one vs. multiple exit points. Yes, I will agree that having multiple exits can make the code harder to read, but the key word here is "can". In the "real world", coding is done by humans and humans can determine when to follow guidelines and when to break them. The code being discussed is a perfect example of when multiple returns can be perfectly clear.
BTW, the only rule I use is one that says the word "shall" shall not be used in coding guidelines.
uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3) { if (int1 !=3D 32) return 3; if (int2 !=3D 16) return 2; if (int3 !=3D 8) return 1; return 0; }
Very short and still perfectly clear! Actually, this is starting to look a bit like Forth! There is a technique in Forth where you use a semicolon in the middle of a definition as a return. This serves as the terminator of the then part of a definition so it would look like
: Func1 int1 32 if 3 ; int2 16 if 2 ; int3 8 if 1 ; 0 ;
Normally a semicolon terminates a definition, but in this case it is equivalent to a return. I don't expect people here to appreciate this since it will obviously offend the sense of style if you are used to using brackets on single statement blocks. But Forth can have its own sense of style and greatly encourages paring down complexity allowing the simplicity of the algorithm to emerge.
If by "real men", you mean gen-X metrosexuals who require a mouse and gui to run an operating system, then perhaps. In fact, when real men have a question, the first thing they do is type "man" -- that ALWAYS helps 8-).
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.