pyscripter 689 Posted September 12, 2021 The following statement compiles under Delphi 11 64 bits but produces an error in 32 bits. Assert.AreEqual(Rec.SubRecord.DoubleField, 3.14); [dcc32 Error] WrapDelphiTest.pas(357): E2532 Couldn't infer generic type argument from different argument types for method 'AreEqual' Here is the definition of Assert.AreEqual class procedure Assert.AreEqual<T>(const expected, actual: T; const message: string); Any idea why? Share this post Link to post
pyscripter 689 Posted September 12, 2021 50 minutes ago, Kryvich said: is the third argument optional? Yes. Share this post Link to post
Guest Posted September 12, 2021 If i would guess, then i will go this, considering compiler has a brain similar in size to a banana brain, it did handled the constant 3.14 as single then refused to compile. Would replacing Assert.AreEqual(Rec.SubRecord.DoubleField, 3.14); with Assert.AreEqual(Rec.SubRecord.DoubleField, Double(3.14)); helps ? Share this post Link to post
Uwe Raabe 2057 Posted September 12, 2021 My guess is, in 64 bit Double and Extended are the same and constants are Double, but in 32 bit they are different and constants are Extended. The DoubleField matches the Double and Extended type as well as the Extended constant does, so the compiler doesn't know what to select. 1 Share this post Link to post
Guest Posted September 12, 2021 8 minutes ago, Uwe Raabe said: in 64 bit Double and Extended are the same and constants are Double, but in 32 bit they are different and constants are Extended. The DoubleField matches the Double and Extended type as well as the Extended constant does, so the compiler doesn't know what to select. To confirm this theory i tried this procedure WriteIt(V: Single); overload; begin Write('Single = '); Writeln(V); end; procedure WriteIt(V: Double); overload; begin Write('Double = '); Writeln(V); end; procedure WriteIt(V: Extended); overload; begin Write('Extended = '); Writeln(V); end; { procedure WriteIt(V:Extended80);overload; begin Write('Extended80 = '); Writeln(V); end; } procedure Test; begin WriteIt(3.14); end; Extended and Extended80 are the same type on both bitness builds, but also the compiler is choosing Extended(Extended80) on both platforms. And that bring us back to the theory of banana brain ! It seems and might be true though, the monkey (compiler) start to dance when see generics (bananas) Share this post Link to post
pyscripter 689 Posted September 12, 2021 @Uwe Raabe@Kas Ob. You are both right. double(3.14) resolves the problem. The documentation at Floating Point Constants - RAD Studio (embarcadero.com) states that "In the absence of any suffixes, floating-point constants are of type double. " This is irrespective of the compiler target. Is this a documentation error? Share this post Link to post
Uwe Raabe 2057 Posted September 12, 2021 23 minutes ago, pyscripter said: The documentation at Floating Point Constants - RAD Studio (embarcadero.com) states that "In the absence of any suffixes, floating-point constants are of type double. " That is for C++, while in Delphi 32 Bit they are Extended. See Declared Constants Quote If constantExpression is a real, its type is Extended. 1 Share this post Link to post
Guest Posted September 12, 2021 14 minutes ago, Uwe Raabe said: That is for C++, while in Delphi 32 Bit they are Extended. See Declared Constants Quote If constantExpression is a real, its type is Extended. Well, there is the following argument 1) We are not talking constant expression, but simple untyped constant, this is very important though, as the behaviour even for constant integer expression one might call it buggy or inconsistent. 2) Now to my test above, the compiler didn't accept the existence of the Extended and Extended80 as overloaded, means they are identical types, but it accept Double and Extended and choose Extended, if we removed the Extended version, the compiler choose Double over Single, and if we left only Single the compiler will not complain and forward it there, all of that without a warning because it will be ugly and stupid to warn about such thing. But it comes to the proc with generics, it failed to behave the same, i mean simple "3.14" is untyped and the compiler should have showed some personality and intuitive more than a banana ( or a car, i know you have a thing for such examples ) , i see this as compiler bug or inconsistency in behaviour, what do you think ? Share this post Link to post
EugeneK 19 Posted September 14, 2021 Same happens with Integers, you have to write for example Assert.AreEqual(1, Integer(Length(smth))); it is very annoying, I wonder if there is a way to fix it in DunitX? Share this post Link to post
Guest Posted September 14, 2021 18 minutes ago, EugeneK said: it is very annoying, I wonder if there is a way to fix it in DunitX? I think the compiler should be fixed first before fixing any library, because fixing generics or DUnitX based on faulty compiler is just wrong and will breaks things even more. example : This will not compile, on both 32bit and 64bit. var UI64: UInt64; begin UI64 := 1 shl 31; // [dcc64 Error] : E1012 Constant expression violates subrange bounds // also this var UI32: Cardinal; begin UI32 := 1 shl 31; While this will compiler fine var UI64: UInt64; begin UI64 := 1 shl 32; // UI64 value is 1 there is so many wrong with constants and even more problem with constant expressions that can be listed in one post. Share this post Link to post
Guest Posted September 14, 2021 adding one more exotic example, just to point to a fact that a Delphi application by luck works to some extend const T: Integer = 1; procedure Test; var UI64: UInt64; begin UI64 := T shl 31; // UI64 = 18446744071562067968 !!!!!!!!!!!!!!!! Share this post Link to post
Guest Posted September 14, 2021 Three more of these gems, in case someone thinks the bug in bit shifting (shl) const T: Integer = 1; procedure Test; var UI64: UInt64; begin // this is fine UI64 := T * 256 * 256 * 256 * 64; // = 1073741824 // WTF with the following error UI64 := 1 * 256 * 256 * 256 * 128; // [dcc64 Error] : E2099 Overflow in conversion or arithmetic operation // This is fine UI64 := Int64(1) * 256 * 256 * 256 * 256; // = 4294967296 // Again WTF UI64 := T * 256 * 256 * 256 * 128; // = 18446744071562067968 Share this post Link to post
Vincent Parrett 750 Posted September 15, 2021 8 hours ago, EugeneK said: it is very annoying, I wonder if there is a way to fix it in DunitX? I'm open to suggestions - but really this is a Delphi compiler issue and I'm not sure what else I could do to work around it. Share this post Link to post
Lars Fosdal 1792 Posted September 15, 2021 Have these been reported in the QP? Share this post Link to post
Darian Miller 361 Posted September 15, 2021 On 9/14/2021 at 12:39 PM, Kas Ob. said: Three more of these gems, in case someone thinks the bug in bit shifting (shl) const T: Integer = 1; procedure Test; var UI64: UInt64; begin // this is fine UI64 := T * 256 * 256 * 256 * 64; // = 1073741824 // WTF with the following error UI64 := 1 * 256 * 256 * 256 * 128; // [dcc64 Error] : E2099 Overflow in conversion or arithmetic operation // This is fine UI64 := Int64(1) * 256 * 256 * 256 * 256; // = 4294967296 // Again WTF UI64 := T * 256 * 256 * 256 * 128; // = 18446744071562067968 I get E2099 in 10.4.2 at compile time so it's not a new issue. In RS11 I get integer overflow at runtime on the last one so there is some change in default behavior since 10.4.2 Share this post Link to post