Why is this NOT unreachable in the if-statement? - 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;
}
}

Related

Difference between flow of if....if block and if....else block

So I was just solving this question the previous day
https://leetcode.com/problems/search-a-2d-matrix-ii/
I was able to solve the problem....but was confused in the execution of if...else block vs if...if block.
The if...else block didn't give me any error while the if....if block gave me an error of IndexOutOfBoundException for length = 1.
Can someone please tell me what's the difference in Layman's term and what am I doing wrong here?
Here is my code ---->
class Solution {
public boolean searchMatrix(int[][] m, int target) {
int x =m.length;
int n= m[0].length;
int i = 0 , j=n-1;
while(i<x && j>=0){
if(m[i][j]==target){
return true;
}
if(m[i][j]>target){
j--;
}
if(m[i][j]<target) {
i++;
}
}
return false;
}
}
************************************* VS ******************************************
class Solution {
public boolean searchMatrix(int[][] m, int target) {
int x =m.length;
int n= m[0].length;
int i = 0 , j=n-1;
while(i<x && j>=0){
if(m[i][j]==target){
return true;
}
if(m[i][j]>target){
j--;
}
else {
i++;
}
}
return false;
}
}
One issue is that this can take you off the bottom of your matrix if j=0.
if(m[i][j]>target){
j--;
}
if(m[i][j]<target) {
i++;
Let's say m[3][0] > target, and you subtract 1 from j, giving j=-1. In your if-else solution, the else is skipped, the while loop then sees that j<0, and the loop exits. Fine.
But in your if-if solution, it then executes if(m[3][-1]<target), which causes the IndexOutOfBoundException
There may be other scenarios too - I haven't checked.

Error: control may reach end of non-void function in C++

I cannot figure out why this error is happening: error: "control may reach end of non-void function" even when "else" statement is present at the end.
Here is the code:
bnode* binsert(bnode *h,int k){
bnode *temp=new bnode;
if(h==NULL)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h=temp;
return h;
}
else if(h->L==NULL && k<h->num)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h->L=temp;
return h;
}
else if(h->R==NULL && k>h->num)
{
temp->num=k;
temp->L=NULL;
temp->R=NULL;
h->R=temp;
return h;
}
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
}
You need to return the results of recursive calls, it's not done automatically.
You can also simplify your code a bit by adding a constructor:
bnode::bnode(int v)
: num(v),
L(nullptr),
R(nullptr)
{
}
and since you're already handling the case of a null parameter, you don't need special cases for null children:
bnode* binsert(bnode *h,int k)
{
if(h == nullptr)
{
h = new bnode(k);
}
else if(k < h->num)
{
h->L = binsert(h->L, k);
}
else if(k > h->num)
{
h->R = binsert(h->R, k);
}
return h;
}
because this last 2 conditions:
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
may occur and no return is given...
you need to be sure the function returns a value no matter what the condition evaluates....
else if(h->L!=NULL && k<h->num)
{
h->L=binsert(h->L,k);
}
else
{
h->R=binsert(h->R,k);
}
In the else if and else cases for your code, if you reach here, you do not return a value, and the behavior is undefined if you try to use this value.
You probably want to add a return h; in the two branches.

Function checking values of type chars

I am new to programming and have an exercise in which I create a function to check whether an array of type char hold particular values.
Here is my function:
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int n1,n2,n3;
for (int i=0;i<size;i++)
{
if (n[i]==pos1)
{
n1=1;
}
if (n[i]==pos2)
{
n2=1;
}
if (n[i]==pos3)
{
n3=1;
}
}
if ((n1==1)&&(n2==1)&&(n3==1))
{
return true;
}
}
here is my test program:
int main()
{
char a[5]={'6','1','a','a','a'};
if (arrCheck(a,'1','6','9',5))
{
cout<<"true\n";
}
}
I thought the result is supposed to be false but all I got is true. What did I do wrong?
n1, n2 and n3 are default-initialized and they have indeterminate values at first. Initialize them before checking their values. Also do not forget to return something even when the condition is false.
Try this:
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int n1=0,n2=0,n3=0;
for (int i=0;i<size;i++)
{
if (n[i]==pos1)
{
n1=1;
}
if (n[i]==pos2)
{
n2=1;
}
if (n[i]==pos3)
{
n3=1;
}
}
return (n1==1)&&(n2==1)&&(n3==1);
}
Using boolto store boolean values and using const to mark that the contents of array won't be changed may be better .
bool arrCheck(const char n[],char pos1,char pos2,char pos3,int size)
{
bool n1=false,n2=false,n3=false;
for (int i=0;i<size;i++)
{
n1=n1||(n[i]==pos1);
n2=n2||(n[i]==pos2);
n3=n3||(n[i]==pos3);
}
return n1&&n2&&n3;
}
1) Use a bool variable instead of three int variable
2) Initialize it (You have not initialized the int variable and they have random garbage value)
3) Also add else condition to return false value (Your code is not returning false).
4)Also print false in main function using else condition.
Hope this helps you..!
THE CODE IS ALRIGHT. You just forgot to add some statements and this is causing the error (it might or might not have been silly on your part).
Your definition of the function arrCheck() is incomplete. It returns true if a certain condition is fulfilled but what if it isn't? In that case, you must return false. But in your code, false is never returned. So firstly, you've gotta add an else statement after the last if statement in the arrCheck() method to this:
if((n1==1)&&(n2==1)&&(n3==1)){
return true;
}
else{
return false; //this has to be added
}
It can now return false if such a case is encountered.
Also, you must display "false" in the main method if arrCheck() returns false. You are recommended to add an else statement after the if statement in the main() method. See the modification below:
if (arrCheck(a,'1','6','9',5))
{
cout<<"true\n";
}
else{
cout<<"false\n"; //it must show false;
}
Once you correct these, your code will produce the correct output.
P.S. This answer serves as an elaboration of the answer earlier submitted by #KUSHAGRA GUPTA.
int n1,n2,n3;
This line leads to undefined behaviour because you do not initialise the variables yet attempt to read from them later on even if not all of them have been assigned a value:
if ((n1==1)&&(n2==1)&&(n3==1))
Fix the undefined behaviour by initialising the variables to 0:
int n1 = 0;
int n2 = 0;
int n3 = 0;
There is another case of undefined behaviour when your function does not state what to return if the condition is not true. Fix this, too:
if ((n1==1)&&(n2==1)&&(n3==1))
{
return true;
}
else
{
return false;
}
Or simply:
return (n1==1)&&(n2==1)&&(n3==1);
change that line to like this.int n1= 0,n2= 0,n3 = 0;
because when uninitialized these variable have garbage values.
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int first = 0,second = 0, third = 0;
for (int i=0;i<size;i++) {
if (n[i]==pos1) {
first = 1;
} else if (n[i]==pos2) {
second = 1;
} else if (n[i]==pos3) {
third = 1;
}
}
if( first+ second + third == 3)
return true;
else
return false;
}

Does an empty "else" clause have any significance in 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.

Error: not all control paths return a value

I am writing two functions in a program to check if a string has an assigned numeric code to its structure array or if the given numeric code has an assigned string in the same structure array. Basically, if I only know one of the two, I can get the other. I wrote the following:
int PrimaryIndex::check_title_pos(std::string title) {
bool findPos = true;
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
} else {
return -1;
}
}
std::string PrimaryIndex::check_title_at_pos(int pos) {
bool findTitle = true;
if (findTitle) {
for (int p = 1; p <= 25; p++) {
if (my_list[p].tag == pos) {
return my_list[p].title;
}
}
} else {
return "No title retrievable from " + pos;
}
}
However, it says not all control paths have a return value. I thought the else {} statement would handle that but it's not. Likewise, I added default "return -1;" and "return "";" to the appropriate functions handling int and string, respectively. That just caused it to error out.
Any idea on how I can keep this code, as I'd like to think it works but cant test it, while giving my compiler happiness? I realize through other searches that it sees conditions that could otherwise end in no returning values but theoretically, if I am right, it should work fine. :|
Thanks
In the below snippet, if s iterates to 26 without the inner if ever evaluating to true then a return statement is never reached.
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
}