Search code examples
c#.net-4.0ilmerge

double.NaN, double.NegativeInfinity, and double.PositiveInfinity all cause compiler errors


I'm working on a project in C# on .NET Framework 4.0, and the mere presence of NaN, -inf, and +inf in my code (see the sample below) causes a compiler error.

This project is based on the NotepadPlusPlusPluginPack.NET, and indeed the same error appears when I introduce those constants in the demo plugin that comes with that repo.

EDIT: It's definitely somehow linked to the plugin pack mentioned above (and speculatively its IlMerge dependency in particular), because I can use those constants in a new .NET 4.0 project with no problems.

For example, any of the first three lines in the block below will raise an error.

double nan = double.NaN;
double neginf = double.NegativeInfinity;
double inf = double.PositiveInfinity;
if (nan == inf || inf == neginf) { }

And no, I don't have to assign a variable to one of those three; just mentioning one of them will throw an error.

My project builds fine otherwise. I can replace every instance of -inf, NaN or +inf with 1d or some other double, and my project will build. And it's not like it builds but it's somehow horribly flawed; every other feature is fine as far as I can tell.

This problem occurs whether I use Visual Studio 2022 or Visual Studio 2019.

Here's a representative line of code and associated error message:

double inf = double.PositiveInfinity;
Severity    Code    Description Project File    Line    Suppression State
Error       
<source code filename>.cs(784) : error : syntax error at token 'inf' in:     IL_03db:  ldc.r8     inf   JsonToolsNppPlugin          

I have built previous projects using these constants in .NET 6.0 and I never had this problem. I just rebuilt another unrelated project in .NET 6.0 and it still works fine.

I can also try introducing these constants into other unrelated projects and they now error out.


Solution

  • This is a hacky solution, but it's better than nothing: generate NaN, inf, and -inf at runtime with something that doesn't get pre-compiled.

    using System;
    
    namespace YourNameSpace
    {
        public class NanInf
        {
            /// <summary>
            /// a/b<br></br>
            /// may be necessary to generate infinity or nan at runtime
            /// to avoid the compiler pre-computing things<br></br>
            /// since if the compiler sees something like literal 1d/0d in the code
            /// it just pre-computes it at compile time
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static double Divide(double a, double b) { return a / b; }
    
            public static readonly double inf = Divide(1d, 0d);
            public static readonly double neginf = Divide(-1d, 0d);
            public static readonly double nan = Divide(0d, 0d);
        }
    }
    

    I tested this in the code where I was having trouble and it works fine.