longint range-check wrongly prevents compile lazarus / 67-Windows ---------------------------------------------------------------------- nanobit · 2018-12-17 11:01 const Dst = $00AA0029;  SrcCopy = $00CC0020; // are longints begin   windows.makerop4( Dst, SrcCopy);  // this call expects longints end; On the call, SrcCopy produces this compile-error: "range check error while evaluating constants (3422560256 must be between -2147483648 and 2147483647)" I noticed the following: This compile error does not occur if I use own functions instead of windows-function. SrcCopy is $00CC0020 (unlike 3422560256 ($CC002000)) Typed "const SrcCopy: longint = $00CC0020;" (correctly) silents the compiler. fpc3.0.4, win32 on Win10; and I cannot debug the RTL (would require different installation) ---------------------------------------------------------------------- Thaddy · 2018-12-17 11:08 No these are unsigned ints......Pointers are unsigned because you can not get below existing memory.... This is a legacy issue, but nowadays the hex notation assumes unsigned and is correct and not your code. You need to cast a hexadecimal to a signed type depending on what is asked by some API. Your code demonstrates this ( and is therefor wrong, because the initial declaration was wrong in the first place). I can understand your frustration because many windows units in Pascal rely on signed types where they should have been unsigned. This is rather common. You found a correct solution: assign to a longint if an API unit expects a longint. In this case it is an API bug.... ---------------------------------------------------------------------- nanobit · 2018-12-17 11:29 Thaddy, no casting in the call is working for me. And SrcCopy is just copied declaration from fpc\3.0.4\source\rtl\win\wininc\defines.inc windows.makerop4( longint(Dst), longint(SrcCopy)); // gives the same error I understand your explanation, but this is not the problem here. ---------------------------------------------------------------------- Thaddy · 2018-12-17 11:29 re-read my reply. I editted it What I wrote is a fact. Casting the hex value to a longint or assigning to a longint is correct. See e.g. https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi- bitblt And hex values are unsigned. ---------------------------------------------------------------------- nanobit · 2018-12-17 11:57 Ok, we have a solution (longint-typed constant) to workaround this, but the following appears still strange: 1) longint typecast placed in the call does not remove the error- message 2) in the error message, $00CC0020 is referred to as 3422560256 ($CC002000) ---------------------------------------------------------------------- Bart · 2018-12-17 12:26 Show us the complete code (a minimal test case) please, not just snippets. Bart ---------------------------------------------------------------------- nanobit · 2018-12-17 13:25 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test;{$R+} uses  windows; const  Dst = $00AA0029;  SrcCopy = $00CC0020;beginwindows.makerop4( longint(Dst), longint(SrcCopy)); { halts with message: "test.lpr(11,1) Error: range check error while evaluating constants (3422560256 must be between -2147483648 and 2147483647)"}end. ---------------------------------------------------------------------- Josh · 2018-12-17 14:28 Hi Not near a computer with Lazarus on at the moment. When I have assigned const hex I explicity declare the type being used ie Const Dst:LongWord=$00AA0029; Does this help? ---------------------------------------------------------------------- nanobit · 2018-12-17 14:43 Only typeless constants don't work. Typed (longword, longint, dword) work. ---------------------------------------------------------------------- Thaddy · 2018-12-17 16:05 Quote from: nanobit on December 17, 2018, 03:43:21 pmOnly typeless constants don't work. Typed (longword, longint, dword) work. That is correct. (As I already pointed out). Hex literals may be even FPC version dependent. Currently hex literals are always UNsigned. E.g: $FF = 255 (a byte value) but shortint($FF) = -1 $FFFF = 65536 (a word value) but smallint($FFFF) = -1 etc.. If you mix integer values with hex literals that will give range errors. The same goes for binary  - % -  literals and octal - & - literals, these are also always UNsigned. Decimal literals are  different depending on value. An cast, or assignment to a var or typed const can change the literal to signed. As you observed. And is the only correct behavior. ---------------------------------------------------------------------- ASerge · 2018-12-17 16:30 I think there is an error in the function implementation (bug). This original implementation:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function MAKEROP4(fore,back : longint) : DWORD; inline;begin  MAKEROP4:=DWORD((DWORD(back shl 8) and $FF000000) or DWORD(fore));end;this corrected implementation:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function MAKEROP4(fore,back : longint) : DWORD; inline;begin  MAKEROP4:=DWORD(((DWORD(back) shl 8) and $FF000000) or DWORD(fore));end;In the original, the expression "back shl 8" is evaluated at compile time (all constants, inline) and causes an error. If you make "DWORD(back) shl 8", no error occurs. ---------------------------------------------------------------------- Thaddy · 2018-12-17 16:40 @ASerge You are right. (for the same theoretical reasons I explained). That is a bug. Here the hex literals are passed as longint parameters - so they are treated as valid longints -, but they need to be treated as unsigned internally to have valid results for the shift. I forgot to look into the underlying code. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function MAKEROP4(fore,back : longword) : longword; inline;begin  result:= back shl 8 and $FF000000 or fore;end; also makes more sense. All the brackets disappear, btw... [edit] Note the version from winunits-jedi is - almost - correct! (Why do some programmers have such trouble with operator precedence? , sigh) I filed bug report 0034712 on Mantis ---------------------------------------------------------------------- nanobit · 2018-12-18 07:39 This explains the value (3422560256) in the error message: The compile error in the project-unit refers to an operation inside the inline code. Not to parameter (SrcCopy = $00CC0020), but to value $CC002000 ( = back shl 8 ). The following gives the same compile-error: const SrcCopy = $00CC0020; // error reported only if untyped var back: longint; d: dword; begin back := SrcCopy; d := dword( back shl 8 ); ---------------------------------------------------------------------- Thaddy · 2018-12-18 07:44 Correct observation: an untyped integer const is always a signed integer type. So assigning a hex value to it has the same issue as you observed before. I am quite sure the bug will be fixed. You can also use my version of makerop4, which is correct and will not give range issues.