Is there way to get rid or find by linting (or maybe sed
ing/regexp
ing) these nasty situations when your have just one line of code after if/for statement, without curly braces? Like this one:
if(condition)
return;
For reference why would I want to get rid of that - there are lots of reasons given in this thread:
What's the purpose of using braces (i.e. {}) for a single-line if or loop?
I maintain some legacy code, and deal with some not-really-finished code from other people, and from time to time stumble on situation when this code-style works like a trip wire when debugging:
if(condition_for_early_return)
LOG("Im here") // surprise surprise, I just broke control logic
return;
Also, I've seen code like that:
if(condition)
<tabs> do_smth();
<spaces> do_smth_else();
Of course if
contains only first do_smth()
, compiler is not confused. But because the do_
functions are visually alligned, I wonder - is this intended behaviour or is it a bug that was never found in this legacy code.
I know cppcheck
does not catch these situation - already tried that.
Do you have any way of finding these traps automatically?
CodePudding user response:
GCC has:
-Wmisleading-indentation (C and C only)
Warn when the indentation of the code does not reflect the block structure. Specifically, a warning is issued for if, else, while, and for clauses with a guarded statement that does not use braces, followed by an unguarded statement with the same indentation.
In the following example, the call to “bar” is misleadingly indented as if it were guarded by the “if” conditional.
if (some_condition ())
foo ();
bar (); /* Gotcha: this is not guarded by the "if". */
In the case of mixed tabs and spaces, the warning uses the -ftabstop= option to determine if the statements line up (defaulting to 8).
The warning is not issued for code involving multiline preprocessor logic such as the following example.
if (flagA)
foo (0);
#if SOME_CONDITION_THAT_DOES_NOT_HOLD
if (flagB)
#endif
foo (1);
The warning is not issued after a #line directive, since this typically indicates autogenerated code, and no assumptions can be made about the layout of the file that the directive references.
Note that this warning is enabled by -Wall in C and C .
Alternatively, clang-format provides:
-InsertBraces (Boolean) clang-format 15
Insert braces after control statements (if, else, for, do, and while) in C unless the control statements are inside macro definitions or the braces would enclose preprocessor directives.
But also issues a warning:
Setting this option to true could lead to incorrect code formatting due to clang-format’s lack of complete semantic information. As such, extra care should be taken to review code changes made by this option.
CodePudding user response:
A quick google showed that SonarSource's linter has a rule for this: https://rules.sonarsource.com/cpp/RSPEC-121
I believe there's a way to use this tool for free to some extent, so it should work.
Alternatively, clang-format supports the option to just add them since v15: https://clang.llvm.org/docs/ClangFormatStyleOptions.html#insertbraces
CodePudding user response:
Clang-tidy actually has a check for that, and if I remember correctly, it can also fix things automatically for you (you should of course then manually go through all the changes and make sure they're correct)