Do you know everything about if?

    How do you place the brackets that you include in the blocks, how do you write logical expressions? .. Do you think that following simple rules, you can not only make the code more readable, but also facilitate debugging, improve diagnostics, and improve performance? .. I

    offer 5K thoughts and links to style guides (hereinafter SG). I hope this article will be a pleasant and easy reading. And I am sure that it does not touch on all issues and I hope for a meaningful discussion.


    Strictly speaking, such things can be written not only about if. It is if that is chosen almost by accident (in the end, why not?). The idea of ​​this article threw f0b0s . Several people supported her (idea) at once, I also began to wait for the article; but never having waited, he decided to raise this banner himself.f0b0s , thanks for the idea, I apologize if I got ahead, I'm waiting for comments.

    For completeness, take a second to commonplace things.

    Braces


    Ideal to write curly braces everywhere, and each expression if / else / else_if

    // WELL
    if (a == b) {
      foo ();
    } else {
      bar ();
    }

    and some SGs recommend writing else on a new line

    // Not
    } else {
    // a
    }
    else {
    // or
    }
    else
    {

    Then else is obtained with the same indentation as the corresponding if. But there is no unity on this issue.

    If you still omit the brackets (which there is no crime), then two aspects must be taken into account. First, follow the same tactics for if and else blocks:

    // LIKE
    if (a == b) {
      foo ();
      bar ();
    } else
      bazzz ();

    And secondly, do not write the whole if on one line

    // VERY BAD
    if (cond ()) act ();
    else err ();

    Mixing styles within the same if / else makes it difficult to read, and placing multiple expressions on the same line also makes debugging difficult; in the last example, cond () and act () are located on the same line; this makes it difficult to find errors by deadline number and debugging.

    And two more notes about blocks


    Create variables only when necessary


    Take advantage of C ++. If the variable is needed only in the block, then create it only in the block.

    // BADLY
    SomeClass p; // only needed in the block
    if (x == y) {
      p.moveTo (x, y);
      p.logResultsOfMovement ();
    }

    // WELL
    if (x == y) {
      SomeClass p; // only needed in the block
      p.moveTo (x, y);
      p.logResultsOfMovement ();
    }

    This will save CPU time, memory ... in general, everything that is so dear to every person who professes humanistic ideals :-)

    First describe the normal course of events.


    In if / else expressions, first describe the normal course of events, and in the else block, handle the handling of emergency situations. This makes reading the program easier:

    // WELL
    bool errorFlag = openConnection ();
    if (! errorFlag) {
      doJob ();
    } else {
      dropJob ();
    }

    Logical expressions


    C ++ not C


    First of all, in C ++ you should not follow the C style of writing

    // BADLY
    if (float_num) {}
    if (int_num) {}

    The C ++ standard does not guarantee that float (0) and even int (0) are implemented as “all bits 0” (although, of course, this works, but this is purely random :-)).

    If you need to check for equality 0, then it is better to write this:

    // WELL
    if (float_num! = .0) {}
    if (int_num! = 0) {}

    Only logical quantities should be used as a condition. This, by the way, also applies to loops:

    // WELL
    while (true) {}
    // BADLY
    while (1) {}
    for (;;) {}

    Separate logical expressions into parts


    If a logical expression consists of several parts, then the worst practice is to write them all to a heap. Is it possible to quickly understand what is written here?

    // BADLY
    if (figureX> leftLimit && figureX <fightLimit && figureColor == GREEN)

    Highlighting, of course, would help, but even without highlighting, the following expression is read much easier:

    // WELL
    if (figureX> leftLimit &&
        figureX <fightLimit &&
        figureColor == GREEN)

    But it’s absolutely ideal to introduce additional variables into the program

    // VERY CUTE
    bool isInside = figureX> leftLimit && figureX <fightLimit;
    bool isGreen = figureColor == GREEN;
    if (isInside && isGreen)

    Such a program is much easier to read, and in addition, the isInside and isGreen variables may come in handy later on.

    And for greater readability, you can put brackets around logical expressions in the first two lines.

    Expressions in conditions


    Expressions are best removed from conditions

    // WELL
    bool dataReaded = readDdata (fileName);
    if (dataReaded) {}

    This makes the code much more readable than

    // BADLY
    if (readDdata (fileName)) {}

    In addition, this echoes the general idea of ​​unloading the logical expression, which was already expressed above, as far as possible.

    And, of course, “each expression has its own line!”

    // VERY BAD
    if (readDdata (getFileNameFromArray (getEnvAsArray ()))) {}

    Again, it’s hard to read, hard to debug, hard to localize errors.

    Assignments under conditions


    For the reasons already stated, it is better not to perform assignments in logical expressions:

    // BADLY
    if (lid = getLabel () == curentLabel ())

    This leads to many troubles. Expansion of a logical expression, placing multiple calls on one line. The appearance of two similar (externally) operators "=" and "==" next to each other, which further complicates reading and increases the likelihood of errors and typos.

    A very common mistake is to write one "=" instead of two ("=="). So that the compiler immediately pulled your hand, some people develop the habit of writing comparisons on the contrary (I admit, I could not develop it in myself :-))

    If you don’t write

    // BADLY?
    if (x == 1)

    a

    // WELL?
    if (1 == x)

    then you can not be afraid to seal and write "=" instead of "==". In a good version, the program simply will not compile if you allow such a typo.

    Seems to have forgotten nothing


    If you forgot something, thanks for the comments :-)

    A couple of good SG:

    Classic SG . Pay attention to the links below - there are even more extensive documents.

    SG from Google . It is worth exploring, since it is not in all solidarity with the aforementioned SG.

    upd Thanks to all who commented! The discussion (as I expected) turned out to be more interesting than the article :-) I do not comment on the article for two reasons. Many remarks (equitable) contradict each other (which is not surprising when discussing such topics). And the second, if I make all the changes, the discussion will become completely incomprehensible and the article will lose its best part :-) Let everything remain as it is and the “mistakes” (?) Made in the article will illustrate the discussion.

    Also popular now: