Reputation: 750
When I tried a sample expression in C# in Visual Studio
public int Test()
{
if (10/2 == 5)
throw new Exception();
return 0;
}
When I keep the expression 10/2 == 5, the vs.net automatically throws a warning "Unreachable Code Detected".
If I change the expression 10/2 == 6, the IDE is happy? How does it happen?
Edited: Sorry for the incomplete question. It happens so instantly and happens even before compiling the code?
I have upvoted each of the replies and accepted the first answer on FIFO basis
Upvotes: 5
Views: 419
Reputation: 61952
As others have said, the compiler can evaluate the expression 10 / 2 == 5
compile-time because it's a constant expression. It evaluates to true
, therefore any code after the if
scope is unreacable. If changed to false
, the code inside the if
is unreachable.
So now consider this code:
public int TestA()
{
if (10 / 2 == 5)
return 1;
return 0;
}
public int TestB()
{
if (10 / 2 == 6)
return 1;
return 0;
}
Both methods generate a warning about unreachable code!
The strange thing about the C# compiler is that if the unreachable code consists entirely of throw
statements, then no warning will be issued about the unreachabiliy.
ADDITION: This Stack Overflow question is related
Upvotes: 4
Reputation: 67065
If you decompile this code, you will end up with:
public int Test()
{
throw new Exception();
}
I believe that since these are constant values, that the math is done at compile time, so 10/2 is not really 10/2, but 5...so it becomes trivial for the compiler to realize that 5==5 is always going to be true. In fact, I believe these constants will then automatically be translated into true. The compiler's goal is to optimize out code that is ALWAYS going to repeat and run the processing of it at compile time, rather than running the same processing over and over.
So, basically, the compiler realizes that since the if is always true
and the if results in a return
(via a throw
), so it optimizes out the code that it knows will never be executed. Thus, the decompiled code results in the above.
In fact, the opposite happens if you do the 10/2 == 6
, which is "constantized" into 5 == 6, which is turned into false. Since the if will always be false, it optimizes out the if:
public int Test()
{
int num = 0;
return num;
}
Upvotes: 4
Reputation: 813
In fact he knows he will never come in return 0
He just warns that the entire code below the 10/2 == 5 will never be interpreted as 10/2 will always be 5.
In the same way:
if (true)
{
......
}
else
{
.....
}
Upvotes: 1
Reputation: 18600
The compiler is smart enough (this is a very simple check) and determines that return 0 will never be reached. This is because 10/2 == 5 will always be true. According to the compiler, the following expressions evaluate equally
if (10/2 == 5)
or
if true
The reason the compiler is able to determine this is because the numbers are not variable.
Upvotes: 1
Reputation: 8986
It is complaining that the line
return 0;
can never be reached. 10/2 is always equal to 5.
Upvotes: 3
Reputation: 2974
In the first case, the compiler processes the expression 10/2 == 5
, which evaluates to true, so the exception is thrown and the return 0
statement is unreachable.
In the second case, 10/2 == 6
evaluates to false, so the return 0
statement is reachable as the exception is not thrown.
In response to your edit: Your code does not have to actually compile for the compiler to know that the line of code is unreachable. It is smart enough to know that 10/2 == 5
is ALWAYS true, regardless of any user input, meaning the exception will always be thrown.
Upvotes: 2
Reputation: 1321
if (10/2 == 5)
Will always return true, which means
throw new Exception();
Will always be executed, and
return 0;
Will never be reached
Upvotes: 9