¿Escribir declaraciones de flujo de programa redundantes por razones de claridad u optimización?

I am tagging this as C, though it certainly applies to many languages. The reason for this is the part of the question dealing with optimization, which is compiler dependent.

Sometimes we encounter situations like this in programs:

if(bob == 42)
{
    /* ... */
    return;
}
else
{
    /* ... */    
}

La else block here is not strictly necessary, as you can probably see. The same thing also occurs with other program-flow-controlling structures; some "ordinary" constructs are made redundant because of special conditions. The question is: Is there a reason to write these redundant blocks of code? Clarity? Could it possibly help a compiler with optimizations, if the situation was complex enough?

preguntado el 08 de enero de 11 a las 23:01

4 Respuestas

I refer to what you've written as "self-documenting code". By using the else block, you make it easier for people to see that if bob does not equal 42 the 2nd block of code will fire.

In my computer science classes, we would be given code samples like this to test our logical skills. But in the business world, you really don't want to confuse people or do anything that could slow down progress. Therefore, you should opt for whatever is easiest to read assuming the performance hit is negligible.

Self-documenting code means that the explanation of what is going on can be seen in the function names or by reading the actual code, reducing the need for code comments.

As far as running the code goes, do some tests with some timing code to see what performs better.

Respondido el 09 de enero de 11 a las 02:01

+1, good point with the profiling. Probably no general rule here when it comes to performance. When it comes to readability, that is of course a subjective thing. I suppose some would find a lot of unnecessary nested else blocks hard to read. - Oystein

Profiling? Really? That's seems like a lot of work for something that any modern compiler likely treats the same way. It seems highly unlikely that a profiler would even show a difference even if the compiler generated different code. (If one is really interested, I'd say looking at the assembler being generated.) - Davep

@davep: Of course, no one cares in the bob-example, but I could imagine more complex scenarios where it would be useful to analyze the differences (not so much in C, maybe, but definitely in C++). - Oystein

@davep: also, one does not always use GCC or MVC. I would imagine that the question is more relevant if one is programming for an embedded system with a bad compiler/very limited resources. - Oystein

Øystein: Yes, it -could- possibly be an embedded system. But since it's not mentioned at all in this very-general question, it seems highly unlikely. It would additionally seem unlikely that this issue would be a performance issue in particular. Looking at the assembler produced might be a faster way to see if the compiler even produces different code. - Davep

For myself, I often write

if(bob == 42)
{
    /* ... */
    return;
}
/* else */

/* ... */

though I might be missing something here.

EDIT: I also just realized the scope issue here. At least in C++ (not in old C, not sure about C99?) the else block would have it's "own" different scope, which might be worth taking note of.

Respondido el 09 de enero de 11 a las 02:01

I typically use the following comment structure for if statements:

/* Is bob 42 ? */
if(bob == 42)
{
  /* Bob is 42, return from function */

  return;
}
else
{
  /* Bob is not 42, do nothing */
}

The compiler should optimize out the empty else clause.

Respondido el 09 de enero de 11 a las 02:01

If this illustrates the kind of comments some one might actually write, I'll point out that changing 42 to some other number requires changing 4 lines of code instead of just one. Or, it's an efficient way to create 2-3 wrong comment. (I'll agree that the compiler won't care about the "redundant" else.) - Davep

True. The comments are worthy writing when they say something more than the code below them says. And if the code doesn't say anything, it's often better to make the code more self-documenting than document it. - Kos

I'd prefer just one line (if that is equivalent to what you meant)

if (bob == 42) return;

This just says what it does and needs no extra comment. In the contrary, putting in else with a block and comments and stuff obfuscates the code and distracts from what is going on, in particular from the important other code that might follow.

Repeating the same message with little modifications in comments is taking the reader of the code for stupid.

If that was not what you meant with your code snipset, if there is really something to do in both cases, I'd prefer

if (bob == 42) {
  /* do something if bob is the chosen one */
} else {
  /* for all others apply the standard treatment */ 
}
return;

This doesn't hide your return statement deep within a block.

In summary, if you feel that you'd have to comment on your flow control and not on the semantics of your code, you are doing something wrong.

Respondido el 09 de enero de 11 a las 13:01

No, don't do that (the single line thing)! It makes it harder to step through when debugging. - Davep

@davep: wow, what an argument. Just putting it on two lines with an indented return would that fit your needs? So that the evaluation of the expression and the return statement get different line numbers? Otherwise I have to say that hopefully the code is read more often as is, but with the help of a debugger. Again I would say about the same thing as at the end of my answer: if in such a case you can't distinguish where you are with your debugger, well there is something wrong in your design in the first place. - Jens Gustedt

Your comment a bit hard to follow. Yes, two separate lines. I didn't say one "can't distinguish" (you are creating a straw man). It's just harder to step through the code for no benefit. So, you have a problem "hiding your return statement deep within a block" but you don't have a problem hiding at the end of a line? If your conditional is really long, then the crucial return will be obscure being off to the right (maybe, even hidden off the screen). - Davep

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.