Incorrect compiler warning when comparing struct with null

Consider the following code:

DateTime t = DateTime.Today; bool isGreater = t > null; 

With Visual Studio 2010 (C # 4, .NET 4.0), I get the following warning:

warning CS0458: The result of the expression is always "null" of type "bool?"

This is not true; the result is always false (like bool ):

Now the DateTime structure overloads the > (more) operator. Any invalid structure (e.g. DateTime) is implicitly converted to the corresponding type Nullable<> . The above expression is exactly equivalent

 bool isGreater = (DateTime?)t > (DateTime?)null; 

which also generates the same wrong warning. Here, the > operator is cleared . This works by returning false if HasValue either of the two operands is false . Otherwise, the operator raised will go to expand the two operands to the base structure, and then cause the overload > defined by this structure (but this is not necessary in this case, when one operand does not have HasValue ).

Can you reproduce this error and this error is known? I didnโ€™t understand something?

This is the same for all types of structures (not simple int types, not enumeration types) that overload the corresponding operator.

(Now, if we use == instead of > , everything should be completely similar (because DateTime also overloads the == operator), but that doesn't look like it. If I say

 DateTime t = DateTime.Today; bool isEqual = t == null; 

I get a warning no โ˜น Sometimes you see that people randomly check a variable or parameter for null, not realizing that the type of their variable is a structure (which overloads == and which is not a simple type of type int ). It would be better if they received a warning.)




Update: Using the Visual Studio 2015 C # 6.0 compiler (based on Roslyn ), the invalid message from isGreater above is changed to CS0464 with the correct and useful warning message. In addition, the lack of warning with isEqual above is fixed in the VS2015 compiler, but only if you compile with /features:strict .

+11
comparison c # compiler-warnings nullable lifted-operators
Oct 24 '12 at 9:10
source share
3 answers

You are right: this is a bug in Visual Studio . The C # 4.0 standard (ยง 7.3.7 operators with raising) has the following:

For relational operators

 < > <= >= 

[...] The raised statement returns false if one or both operands are equal to zero. ...

And in fact, in MonoDevelop you will receive the following warning:

The result of comparing a System.DateTime type with null always false .

+5
Oct 24
source share

I discovered this error independently when implementing elevated operator behavior in Roslyn, and I fixed it in Roslyn before I left.

Sorry I didnโ€™t see this when you posted it back in October. Thanks for sending it to Connect! And many apologies for the mistake; this is a long-term error in the semantic analysis of the operator.

By the way, I will discuss how Roslyn optimizes captured expressions at http://ericlippert.com later this month (December 2012), so if you are interested in this question, check:

http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/

+9
Dec 19
source share
 DateTime t = DateTime.Today; bool isGreater = (DateTime?)t > (DateTime?)null; 

In this case, the warning is t > null . That will never be true. Because it cannot be appreciated.

In this case:

 bool isGreater = (DateTime?)t > (DateTime?)null; 

We evaluate (DateTime?)t > (DateTime?)null ;

Or essentially at best t > null ; like before. DateTime.Now can never exceed Undefined, so a warning.

+1
Oct 24 '12 at 9:19
source share



All Articles