当前位置:网站首页>Serious bugs with lifted/nullable conversions from int, allowing conversion from decimal

Serious bugs with lifted/nullable conversions from int, allowing conversion from decimal

2022-07-05 02:00:00 Rich in starch

problem :

I think this question will bring me instant fame here on Stack Overflow. I think this question will make me in Stack Overflow Become famous immediately .

Suppose you have the following type: Suppose you have the following types :

// represents a decimal number with at most two decimal places after the periodstruct NumberFixedPoint2{    decimal number;    // an integer has no fractional part; can convert to this type    public static implicit operator NumberFixedPoint2(int integer)    {        return new NumberFixedPoint2 { number = integer };    }    // this type is a decimal number; can convert to System.Decimal    public static implicit operator decimal(NumberFixedPoint2 nfp2)    {        return nfp2.number;    }    /* will add more nice members later */}

It has been written such that only safe conversions that don't lose precision are allowed. It is written so that only safe conversions are allowed without losing accuracy .However, when I try this code: however , When I try this code :

    static void Main()    {        decimal bad = 2.718281828m;        NumberFixedPoint2 badNfp2 = (NumberFixedPoint2)bad;        Console.WriteLine(badNfp2);    }

I am surprised this compiles and, when run, writes out 2 . I'm surprised at this compilation , And at runtime Write 2 .The conversion from int (of value 2 ) to NumberFixedPoint2 is important here. from int ( value 2 ) To NumberFixedPoint2 The transformation of is very important here .(An overload of WriteLine that takes in a System.Decimal is preferred, in case anyone wonders.)( If anyone wants to know , Better accept System.Decimal Of WriteLine heavy load .)

Why on Earth is the conversion from decimal to NumberFixedPoint2 allowed? Why is it allowed on earth from decimal To NumberFixedPoint2 Transformation ?(By the way, in the above code, if NumberFixedPoint2 is changed from a struct to a class, nothing changes.)( By the way , In the code above , If NumberFixedPoint2 From structure to class , There is no change .)

Do you know if the C# Language Specification says that an implicit conversion from int to a custom type "implies" the existence of a "direct" explicit conversion from decimal to that custom type? You know, C# Whether the language specification is from int Implicit conversion to custom types “ Hint ” Whether there is from decimal To this custom type “ direct ” Explicit conversion ?

It becomes much worse. It's getting worse .Try this code instead: Please try this code :

    static void Main()    {        decimal? moreBad = 7.3890560989m;        NumberFixedPoint2? moreBadNfp2 = (NumberFixedPoint2?)moreBad;        Console.WriteLine(moreBadNfp2.Value);    }

As you see, we have (lifted) Nullable<> conversions here. As you can see , Here we are ( promote ) Nullable<> transformation .But oh yes, that does compile. But oh , Yes , That really compiles .

When compiled in x86 "platform", this code writes out an unpredictable numeric value. stay x86 “platform” At compile time , This code will write unpredictable values .Which one varies from time to time. Which one changes from time to time .As an example, on one occasion I got 2289956 . for instance , Once I got 2289956 .Now, that's one serious bug! Now? , This is a serious mistake !

When compiled for the x64 platform, the above code crashes the application with a System.InvalidProgramException with message Common Language Runtime detected an invalid program. When it comes to x64 Platform compile time , The above code is used System.InvalidProgramException Crash the application , And display the message Common Language Runtime Invalid program detected .According to the documentation of the InvalidProgramException class: according to InvalidProgramException Class :

Generally this indicates a bug in the compiler that generated the program. Usually , This indicates an error in the generated program in the compiler .

Does anyone (like Eric Lippert, or someone who has worked with lifted conversions in the C# compiler) know the cause of these bugs? Is there anyone ( such as Eric Lippert, Or once in C# The person who has removed the conversion in the compiler ) Know the reasons for these mistakes ?Like, what is a sufficient condition that we don't run into them in our code? such as , What are the sufficient conditions for not encountering them in our code ?Because the type NumberFixedPoint2 is actually something that we have in real code (managing other people's money and stuff). because NumberFixedPoint2 Types are actually what we have in actual code ( Manage other people's money and things ).


Solution :

Reference resources : https://stackoom.com/en/question/1Expv
原网站

版权声明
本文为[Rich in starch]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202141004159291.html