Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change this condition so that it does not always evaluate to 'true'

Tags:

c#

.net

sonarqube

Why is SonarQube complaining about this part of the code?

enter image description here

I checked this code and not always this value is true.

public static void WriteJson(object value)
{
    decimal decimalValue = ((decimal?)value).Value;
    int intValue = (int)decimalValue;
    if (decimalValue == intValue)
        Console.WriteLine(intValue);
    else
        Console.WriteLine(decimalValue);
    Console.ReadKey();
}

Why is SonarQube complaining about this?

like image 918
pollpbl Avatar asked Sep 01 '17 09:09

pollpbl


2 Answers

The false positive is related to an imperfection in our dataflow analysis engine - it does not take into account the casts between floating point and integer numbers (yet) and cannot recognize when a floating point number has been truncated.

I will try to elaborate a bit: the dataflow analysis engine tracks the values of the local variables in the analyzed methods, and when a new value is being assigned to a variable, the engine creates a special object that represents the actual value. When you assign one variable to another variable, that object remains the same. For example:

var x = 5; // the symbol of x is associated with value_0
var y = x; // the symbol of y is associated with value_0
if (x == y) // value_0 is compared with value_0 --> always true

The values we assign do not contain type information (yet) and we cannot detect (yet) changes in cases like yours:

var x = 5.5; // the symbol of x is associated with value_0
var y = (int)x; // the symbol of y is associated with value_0 (wrong)
if (x == y) // false positive

and we generate false positives, but they are relatively rare, because most casts do not generate new values.

Thanks for the feedback, we will be looking into that in the near future.

like image 120
Val Avatar answered Sep 26 '22 14:09

Val


Looks like SonarQube detects that you are assigning the same value to both variables, assume that value passed to method is equal to 2

 1. decimal decimalValue = 2 
 2. int intValue = (int)decimalValue;

therefore decimalValue = 2 and intValue = 2

The C# compiler will obviously cast it to int so in case you pass 2.5 the if comparision will not evaluate always to true. But most probably SonarQube is just not aware about the casting. So it assumes always true.

like image 30
DevDio Avatar answered Sep 22 '22 14:09

DevDio