Does an empty "else" clause have any significance in C++? - c++

Is there any difference between the following 2 codes functionally? If not, is there a preferred style?
int main()
{
int i=11;
if (i > 100)
{
i = 100;
}
else if (i < 0)
{
i = 0;
}
cout << i << endl;
}
versus
int main()
{
int i=11;
if (i > 100)
{
i = 100;
}
else if (i < 0)
{
i = 0;
}
else
{
}
cout << i << endl;
}
In other words, my question is, is there any point in including the else if I don't want it to do anything?

Significance
To the question:
...does an empty else clause have any significance?
in the context of if { ... } else {} the answer is no. Compilers will probably optimize your else out. Unless you put actual statements (assert, print, error handling) the executable will be virtually identical.
Benefits
To the question:
What are the benefits of an empty else clause in an else if construct?
the answer is discussed at length on this Stack Overflow post. See MISRA publication MISRA C:2012, 15.7 (All if…​else if constructs shall be terminated with an else statement).
It applies to if { ... } else if { ... } else {} construct, not if { ... } else {} construct.
Style
An else { /* no statement */ } in immensely better than an else statement. It does prevent dangling else closures (else not followed by {}) which are downright dangerous since they may mislead a reader of what else actually applies to, and is prone to maintenance errors.
You will find more programming styles1 than you have engineers in a room. May I suggest:
int main() {
int i = 11;
if (i > 100) {
i = 100;
} else if (i < 0) {
i = 0;
}
cout << i << endl;
}
1 each individual, plus one for the consensus.

Related

Why is this NOT unreachable in the if-statement?

In testOne:
Why is the "else if" not unreachable (aNumber is final so the compiler should know it can't get past the "if" part, but it only gives a warning)?
Since "else if" apparently is reachable, why then is the "else" part not unreachable ("else if" is always true)?
In testTwo:
The "if (true)" is unreachable.
Is all this because the compiler somehow thinks my variable and boolean can change even if they are final("aNumber") and hardcoded("true"). And when there is no variable or boolean (the first "else" in testTwo) nothing can change, and since it mops up all possibilities by just saying "else" it knows it cant reach anything further down?
public int testOne() {
final int aNumber = 5;
if (aNumber < 10) {
return 0;
} else if (true) {
return 2;
} else {
return 3;
}
}
public int testTwo() {
final int aNumber = 5;
if (aNumber < 10) {
return 0;
} else {
return 1;
}
if (true) {
return 3;
} else {
return 4;
}
}

What is the problem with this boolean function?

I was wondering what I may have done wrong in writing this simple function which is supposed to return true if the given number is a prime, or false if not a prime.
bool isPrime(int num)
{
if (num <= 1)
{
status = false;
}
else
{
for (int i = 1; i <= num; i++)
{
if (num % i == 0)
{
dividers++;
}
}
if (dividers == 2)
{
status = true;
}
else
{
status = false;
}
}
return status;
}
Obviously, my main looks like this:
bool isPrime(int num);
bool status;
int dividers = 0;
int main() {
isPrime(2);
if (!isPrime)
{
std::cout << "Not prime" << std::endl;
}
else
{
std::cout << "Prime" << std::endl;
}
return 0;
}
I'm a C++ beginner and I'd really appreciate it if someone could help me there and correct my logic.
Have a good day:)
The immediate problem is in this two lines:
isPrime(2);
if (!isPrime)
The first line calls the function and discards the returned value. The second line converts a pointer to the function to bool. The output of your code does not depend on what you actually do in isPrime.
That is not how you call a function and use its result!
Instead you want
if (isPrime(2)) {
or
bool isP = isPrime(2);
if (isP) { ...
As mentioned in comments, there are also problems in the implementation of isPrime, but I hope this is enough to set you back on the right track.
PS: You should get rid of the global variable status. You do not need both, the return value and a global that stores the result, and if you can choose, you should definitely go for the return value.

Clang Format chained else ifs on single lines

I'm trying to write a .clang-format file that will allow the following:
if (value.Is<bool>()) { index = 1; }
else if (value.Is<int>()) { index = 2; }
else if (value.Is<unsigned int>()) { index = 3; }
else if (value.Is<long long>()) { index = 4; }
else if (value.Is<unsigned long long>()) { index = 5; }
else if (value.Is<float>()) { index = 6; }
else if (value.Is<double>()) { index = 7; }
else if (value.Is<long double>()) { index = 8; }
else if (value.Is<std::string>()) { index = 9; }
else if (value.IsArray()) { index = 10; }
else { index = 0; }
I've tried every option I can find related to breaks and allowShort*, and no matter what I do it seems to split them into multi-lines after the first like so:
if (value.Is<bool>()) { index = 1; }
else if (value.Is<int>()) {
index = 2;
}
...
Is there some option I'm missing that could support this?
Unfortunately, this is currently not supported for if-else statements, only for simple if's (as of revision 329373, dating 6/4/18). The AllowShortBlocksOnASingleLine and AllowShortIfStatementsOnASingleLine options are not applicable for if-else statements.
Hopefully this will change in the future.
The doc is not explicit about this, saying that AllowShortIfStatementsOnASingleLine will allow simple if statements on a single line:
AllowShortIfStatementsOnASingleLine (bool)
If true, if (a) return; can be put on a single line.
However, clang-format code suggests that if-else blocks are not allowed on single lines:
1) UnwrappedLineFormatter.cpp, tryMergeSimpleControlStatement:
// Only inline simple if's (no nested if or else).
if (I + 2 != E && Line.startsWith(tok::kw_if) &&
I[2]->First->is(tok::kw_else))
return 0;
2) FormatTest.cpp, FormatShortBracedStatements test.
Notice the test parameters, and that in the expected formatting in the unittests, else always resides in its own line, while plain if statements with no else are on a single line with their blocks, for example:
verifyFormat("if (true) {\n"
" f();\n"
"} else {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
https://clang.llvm.org/docs/ClangFormatStyleOptions.html says:
SIS_AllIfsAndElse (in configuration: AllIfsAndElse) Always put short ifs, else >ifs and else statements on the same line.
if (a) return;
if (b) return;
else return;
if (c) return;
else {
return;
}

How to limit a decrement?

There is a initial game difficulty which is
game_difficulty=5 //Initial
Every 3 times if you get it right, your difficulty goes up to infinity but every 3 times you get it wrong, your difficulty goes down but not below 5. So, in this code for ex:
if(user_words==words) win_count+=1;
else() incorrect_count+=1;
if(win_count%3==0) /*increase diff*/;
if(incorrect_count%3==0) /*decrease difficulty*/;
How should I go about doing this?
Simple answer:
if(incorrect_count%3==0) difficulty = max(difficulty-1, 5);
But personally I would wrap it up in a small class then you can contain all the logic and expand it as you go along, something such as:
class Difficulty
{
public:
Difficulty() {};
void AddWin()
{
m_IncorrectCount = 0; // reset because we got one right?
if (++m_WinCount % 3)
{
m_WinCount = 0;
++m_CurrentDifficulty;
}
}
void AddIncorrect()
{
m_WinCount = 0; // reset because we got one wrong?
if (++m_IncorrectCount >= 3 && m_CurrentDifficulty > 5)
{
m_IncorrectCount = 0;
--m_CurrentDifficulty;
}
}
int GetDifficulty()
{
return m_CurrentDifficulty;
}
private:
int m_CurrentDifficulty = 5;
int m_WinCount = 0;
int m_IncorrectCount = 0;
};
You could just add this as a condition:
if (user words==words) {
win_count += 1;
if (win_count %3 == 0) {
++diff;
}
} else {
incorrect_count += 1;
if (incorrect_count % 3 == 0 && diff > 5) {
--diff
}
}
For example:
if(win_count%3==0) difficulty++;
if(incorrect_count%3==0 && difficulty > 5) difficulty--;
This can be turned into a motivating example for custom data types.
Create a class which wraps the difficulty int as a private member variable, and in the public member functions make sure that the so-called contract is met. You will end up with a value which is always guaranteed to meet your specifications. Here is an example:
class Difficulty
{
public:
// initial values for a new Difficulty object:
Difficulty() :
right_answer_count(0),
wrong_answer_count(0),
value(5)
{}
// called when a right answer should be taken into account:
void GotItRight()
{
++right_answer_count;
if (right_answer_count == 3)
{
right_answer_count = 0;
++value;
}
}
// called when a wrong answer should be taken into account:
void GotItWrong()
{
++wrong_answer_count;
if (wrong_answer_count == 3)
{
wrong_answer_count = 0;
--value;
if (value < 5)
{
value = 5;
}
}
}
// returns the value itself
int Value() const
{
return value;
}
private:
int right_answer_count;
int wrong_answer_count;
int value;
};
And here is how you would use the class:
Difficulty game_difficulty;
// six right answers:
for (int count = 0; count < 6; ++count)
{
game_difficulty.GotItRight();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// three wrong answers:
for (int count = 0; count < 3; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// one hundred wrong answers:
for (int count = 0; count < 100; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
Output:
7
6
5
Once you have a firm grasp on how such types are created and used, you can start to look into operator overloading so that the type can be used more like a real int, i.e. with +, - and so on.
How should I go about doing this?
You have marked this question as C++. IMHO the c++ way is to create a class encapsulating all your issues.
Perhaps something like:
class GameDifficulty
{
public:
GameDifficulty () :
game_difficulty (5), win_count(0), incorrect_count(0)
{}
~GameDifficulty () {}
void update(const T& words)
{
if(user words==words) win_count+=1;
else incorrect_count+=1;
// modify game_difficulty as you desire
if(win_count%3 == 0)
game_difficulty += 1 ; // increase diff no upper limit
if((incorrect_count%3 == 0) && (game_difficulty > 5))
game_difficulty -= 1; //decrease diff;
}
inline int gameDifficulty() { return (game_difficulty); }
// and any other access per needs of your game
private:
int game_difficulty;
int win_count;
int incorrect_count;
}
// note - not compiled or tested
usage would be:
// instantiate
GameDiffculty gameDifficulty;
// ...
// use update()
gameDifficulty.update(word);
// ...
// use access
gameDifficulty.gameDifficulty();
Advantage: encapsulation
This code is in one place, not polluting elsewhere in your code.
You can change these policies in this one place, with no impact to the rest of your code.

return statements when doing Extract Method

Let's say you have a very long method, like this:
int monster()
{
int rc = 0;
// some statements ...
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
// rest of long method...
return rc;
}
and I'm working on skeletonizing the code. I want to extract the dragon slaying part to
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return 0; // ?
}
and replace the code in monster() with a call to handleDragon().
But there is a problem. There is a return statement in the middle of that part. If I keep the part where the return code of handleDragon() is handled, it will keep the litter in the big method.
Besides using exceptions, is there an elegant and safe way to refactor this piece of code out of the monster method? How should these types of situations be handled?
Return 0 from the handleDragon method if the dragon slayer is available:
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
return 0;
}
}
Then back in the monster method, if the return value was greater than zero, return that value, otherwise carry on:
// some statements ...
int handleDragonResult = handleDragon();
if (handleDragonResult > 0) {
return handleDragonResult;
}
// rest of long method...
You should also document the handleDragon method, to explain the value that gets returned.
enum DragonHandled { DHSuccess, DHKing, DHNoKing };
inline DragonHandled askForKing()
{
if (callTheKing())
return DHKing;
else
return DHNoKing;
}
DragonHandled handleDragon()
{
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
return askForKing();
}
cout << "We are saved!\n";
slayTheDragon();
return DHSuccess;
}
int monster()
{
some_statements(...);
DragonHandled handled = handleDragon();
if( handled != DHSuccess )
return handled; // enum to int is an implicit cast
return more_statements(...);
}
Except for a function that returns an actual signed number, I would not return int. If the result has a meaning, define that meaning properly (that is: an enum).
A function does something, and whatever it does, should be visible in its name. So there should be a verb in a function's name (handledragon(), callTheKing()). monsters isn't a verb, it isn't something you can do. If I see an identifier monsters, I'd think it's a container for monsters.
Checking if(x == true) is just useless noise, since if(x) is terser, simpler and just as true.
Couldn't you do this:
int handleDragon() {
int rc = 0;
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
rc = 1;
else
rc = 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return rc;
}
and then:
int monster()
{
int rc = 0;
// some statements ...
rc = handleDragon();
// rest of long method...
return rc;
}
or if you want to do something with the return code:
int monster()
{
int rc = 0;
// some statements ...
int handleDragonReturnCode = handleDragon();
if(handleDragonReturnCode == 0) {
// do something
}
else {
// do something else
}
// rest of long method...
return rc;
}
Is this what you want? On a general note, avoid using magic numbers like 1 and 2 for your return codes. Use constants, #define, or enum.
Concerning return, try to have one exit point from your function. As you have found out, having multiple return statements can make refactoring hard (as well as understanding the logic unless it's really simply).
The question was about the strategy so I think the answer by Richard Fearn is a good one.
To make it into a refactoring pattern it would look something like:
Context: A section in the middle of a larger method is to be extracted.
Problem: The section contains return statements.
Solution:
Extract the code to a new method returning the same type as the larger method.
Find a value of that type that does not mean anything. Call that value CONTINUE.
Add a statement at the end of the new method that returns CONTINUE.
In the larger method test the return value from the new method for CONTINUE. If it is not then return that value.
This would be the principal approach. As the next step you could refactor the return values from the new method to something more meaningful (like in the answer from sbi). And you'd have to find a way to handle the case where the return type isn't a scalar or simple type, returning a NULL object or some such.