A null statement is a statement that does nothing. It is represented by a semicolon (;
).
if (x > 10)
; // this is a null statement
Favor constexpr if
statements over non-constexpr if
statements when the conditional is a constant expression.
if constexpr (gravity == 9.8) // now using constexpr if
{
// code
}
Prefer switch statements over if-else chains when there is a choice. The type of the switch expression must be integral or enumerated.
switch (x) // x type: integral/enumerated
{
int a; // okay: definition is allowed before the case labels
int b{ 5 }; // illegal: initialization is not allowed before the case labels
case 1:
int y; // okay but bad practice: definition is allowed within a case
y = 4; // okay: assignment is allowed
std::cout << "One";
case 2:
{ // note addition of explicit block here
int x{ 4 }; // okay, variables can be initialized inside a block inside a case
std::cout << x;
break; // break instead of return
}
case 3:
std::cout << "Three";
[[fallthrough]]; // intentional fallthrough, execute all future cases
default:
std::cout << "Unknown";
return;
}
Avoid goto
statements unless the alternatives are significantly worse for code readability.
#include <iostream>
int main()
{
double x{};
tryAgain: // this is a statement label
std::cout << "Enter a non-negative number: ";
std::cin >> x;
if (x < 0.0)
goto tryAgain; // this is the goto statement
std::cout << x;
end:
return 0;
}
goto skip; // error: this jump is illegal because...
int x { 5 }; // this initialized variable is still in scope at statement label 'skip'
skip:
x += 3; // what would this even evaluate to if x wasn't initialized?
return 0;
while (true) // infinite loop
for (;;) // infinite loop
A break
statement terminates the switch or loop, and execution continues at the first statement beyond the switch or loop. A return
statement terminates the entire function that the loop is within, and execution continues at the point where the function was called.
#include <iostream>
int breakOrReturn()
{
while (true) // infinite loop
{
std::cout << "Enter 'b' to break or 'r' to return: ";
char ch{};
std::cin >> ch;
if (ch == 'b')
break; // execution will continue at the first statement beyond the loop
if (ch == 'r')
}
// breaking the loop causes execution to resume here
std::cout << "We broke out of the loop\n";
return 0;
}
int main()
{
int returnValue{ breakOrReturn() };
std::cout << "Function breakOrReturn returned " << returnValue << '\n';
return 0;
}
std::exit()
#include <cstdlib> // for std::exit()
#include <iostream>
void cleanup()
{
// closing database or network connections,
// deallocating any memory you have allocated,
// writing information to a log file, etc…
std::cout << "cleanup!\n";
}
int main()
{
std::cout << 1 << '\n';
cleanup();
// or we can
// register cleanup() to be called automatically when std::exit() is called
std::atexit(cleanup); // note: we use cleanup rather than cleanup() since we're not making a function call to cleanup() right now
// The std::exit() function does not clean up local variables in the current function or up the call stack.
std::exit(0); // terminate and return status code 0 to operating system
// The following statements never execute
std::cout << 2 << '\n';
return 0;
}
std::abort()
The std::abort()
function causes your program to terminate abnormally. Abnormal termination means the program had some kind of unusual runtime error and the program couldn’t continue to run.
#include <cstdlib> // for std::abort()
std::abort();