Connie McBride 0 Posted February 12 Using Delphi 12, upgrading from Delphi11, using windows 32 as target. when building, I am getting this error: [dcc32 Errorr E1012 Constant expression violates subrange bounds the errror is in Winapi.Windows const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = Integer($80000000); any ideas how to fix this? Share this post Link to post
Uwe Raabe 2057 Posted February 13 Question: Why are you compiling Winapi.Windows.pas in the first place? 2 Share this post Link to post
Connie McBride 0 Posted February 13 I'm actually not. one of my .pas files is using CW_USEDEFAULT, which is leading to the compile error. Share this post Link to post
DelphiUdIT 176 Posted February 13 4 minutes ago, Connie McBride said: I'm actually not. one of my .pas files is using CW_USEDEFAULT, which is leading to the compile error. Mat be you are using it with UINT32 parameter or something like that ? Share this post Link to post
Uwe Raabe 2057 Posted February 13 43 minutes ago, Connie McBride said: I'm actually not. one of my .pas files is using CW_USEDEFAULT, which is leading to the compile error. Then you seem to have Winapi.Windows.pas in your search path. Otherwise the compiler won't try to compile that issuing that error. Share this post Link to post
David Heffernan 2345 Posted February 13 Step 1 to solving the problem is to understabd why you are compiling delphi rtl libraries Share this post Link to post
Connie McBride 0 Posted February 14 I am building the crystal 13 vcl components for delphi 12. I don't have rtl in my search path Ucrpe.pas is failing on this line : function TCrpe.SendOutput : Boolean; var nLeft, nTop, nWidth, nHeight : DWord; xHandle : hWnd; begin .... if FWindowSize.FLeft = -1 then nLeft := CW_USEDEFAULT <<<<<<HERE nLeft is defined as DWord. so the .pas isn't in my search path, it's the same code that has worked in delphi 10 up to delphi 11.3. Share this post Link to post
Brian Evans 105 Posted February 14 (edited) Looks like different definitions of CW_USEDEFAULT, it can happen for global constants. Add a unit prefix to specify a specific one on the line giving the error. See : Constant with same name in different Unit in Delphi - Stack Overflow Edited February 14 by Brian Evans Share this post Link to post
DelphiUdIT 176 Posted February 14 7 hours ago, Connie McBride said: function TCrpe.SendOutput : Boolean; var nLeft, nTop, nWidth, nHeight : DWord; xHandle : hWnd; begin .... if FWindowSize.FLeft = -1 then nLeft := CW_USEDEFAULT <<<<<<HERE nLeft is defined as DWord. Share this post Link to post
Lajos Juhász 293 Posted February 14 This was changed in D12, in Delphi 11 it was declared as: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = DWORD($80000000); now it's: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = Integer($80000000); 1 Share this post Link to post
Remy Lebeau 1394 Posted February 14 7 hours ago, Lajos Juhász said: This was changed in D12, in Delphi 11 it was declared as: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = DWORD($80000000); now it's: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = Integer($80000000); Which makes sense, as that flag is used primarily with the CreateWindow/Ex() APIs and they accept it as an int, not a dword. Share this post Link to post
Connie McBride 0 Posted February 14 7 hours ago, Lajos Juhász said: This was changed in D12, in Delphi 11 it was declared as: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = DWORD($80000000); now it's: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = Integer($80000000); I changed the variable in the code to be an integer vs a dword, and now it works. but heads up to anyone who runs into this. Share this post Link to post
Remy Lebeau 1394 Posted February 14 2 minutes ago, Connie McBride said: I changed the variable in the code to be an integer vs a dword Why were your variables declared as DWORD to begin with? The Win32 API represents window positions and sizes as ints, not as dwords. Share this post Link to post
DelphiUdIT 176 Posted February 14 31 minutes ago, Remy Lebeau said: Why were your variables declared as DWORD to begin with? The Win32 API represents window positions and sizes as ints, not as dwords. May be this is the cause: 8 hours ago, Lajos Juhász said: This was changed in D12, in Delphi 11 it was declared as: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = DWORD($80000000); now it's: const {$EXTERNALSYM CW_USEDEFAULT} CW_USEDEFAULT = Integer($80000000); Share this post Link to post
Remy Lebeau 1394 Posted February 14 (edited) 1 hour ago, DelphiUdIT said: May be this is the cause: I was referring to this code: 18 hours ago, Connie McBride said: Ucrpe.pas is failing on this line : function TCrpe.SendOutput : Boolean; var nLeft, nTop, nWidth, nHeight : DWord; xHandle : hWnd; begin .... if FWindowSize.FLeft = -1 then nLeft := CW_USEDEFAULT <<<<<<HERE nLeft is defined as DWord. Why were nLeft, etc declared as DWord to begin with and not as Integer, as the Win32 API expects? Edited February 14 by Remy Lebeau Share this post Link to post
Connie McBride 0 Posted February 14 3 minutes ago, Remy Lebeau said: I was referring to this code: Why were nLeft, etc declared as DWord to begin with and not as Integer, as the Win32 API expects? because the library was built to run in delphi11, where cw_usedefault was defined as a dword. that constant changed in delphi12, where it is now an integer Share this post Link to post
Remy Lebeau 1394 Posted February 14 22 minutes ago, Connie McBride said: because the library was built to run in delphi11, where cw_usedefault was defined as a dword. that constant changed in delphi12, where it is now an integer IMHO, just because the constant was DWord doesn't mean the variables should have been DWord. 1 Share this post Link to post
Kas Ob. 121 Posted February 15 14 hours ago, Remy Lebeau said: IMHO, just because the constant was DWord doesn't mean the variables should have been DWord. This inconsistency is very annoying with Delphi compiler, and as you see it, untyped constant should be ... well .... untyped , duh ! , its value i mean in this case numerical value used as needed and casted in place of usage. In this piece the compiler refuse to handle "HandleDWORD(A)" for no logical reason, notice it doesn't have problem with the more dangerous one "HandleInteger(B)" const A = Integer($80000000); B = DWORD($80000000); C = $80000000; D = MINLONG; procedure HandleInteger(Value:Integer); begin Writeln(Value); end; procedure HandleDWORD(Value:DWORD); begin Writeln(Value); end; begin HandleInteger(A); HandleInteger(B); HandleInteger(C); HandleInteger(D); //HandleDWORD(A); // [dcc32 Error] Project5.dpr(36): E1012 Constant expression violates subrange bounds HandleDWORD(B); HandleDWORD(C); HandleDWORD(D); Readln; end. Result on my XE8 Quote -2147483648 -2147483648 -2147483648 -2147483648 2147483648 2147483648 2147483648 I wonder what is the result with Delphi 12 ?! considering there is a change did broke untyped constant handling. Share this post Link to post
DelphiUdIT 176 Posted February 15 37 minutes ago, Kas Ob. said: This inconsistency is very annoying with Delphi compiler, and as you see it, untyped constant should be ... well .... untyped , duh ! , its value i mean in this case numerical value used as needed and casted in place of usage. Uhmm, I think there are good... actually very good reasons why "errors" are generated (AND SHOULD BE) in "Integer and Unsigned Integer" cases and the like. The first and most trivial case is the comparison operation. Comparing (or assigning) integers and unsigned integers is a huge mistake (i.e. it happens in the example from which the topic was generated). I think this is enough to define that there cannot be operations with "automatic" type conversion in these cases. Forcing the operation (therefore through typecasting) is the path that should be followed: the programmer knows what he is doing and solves the problem by forcing the operation. Already the definition of "-1" could create some "stomach ache" (it is an Italian way of saying that it creates "discomfort"). Those who programmed in assembler certainly remember the old Intel CWD-type instructions... 1 hour ago, Kas Ob. said: In this piece the compiler refuse to handle "HandleDWORD(A)" for no logical reason, notice it doesn't have problem with the more dangerous one "HandleInteger(B)" Result on my XE8 I wonder what is the result with Delphi 12 ?! considering there is a change did broke untyped constant handling. A runtime, in Delphi 12 an Error was generated at the second instruction (like you told, "more dangerous") only in Debug mode ('Range check error'), but during compilation many warnings are generated regarding its use. Maybe the Warnings are not enough, they should be switched to error... HandleInteger(B); It is for this reason that it should not be allowed to carry out automatic conversions, already at the compiler level. I use and love Delphi, among other things, because when you write code and compile it you have a good certainty (I said "good" not "sure") that the code will run error-free, at least for basic errors. Share this post Link to post
Kas Ob. 121 Posted February 15 Sorry, I can't agree on the rightness of this, heck.. i might call it rightmess ! Is Delphi 12 compiler handling (and generating machine code for) untyped numerical constant (literal) to be evaluated at runtime ? That is wrong. 52 minutes ago, DelphiUdIT said: but during compilation many warnings are generated regarding its use. It would be great if you or anyone shared these warnings, i only can imagine what could be the case(s), but still when and where the compiler draw the line for such runtime evaluations yet it does accept them at compile time ? Also on side note how the compiler will handle such constants without a type when used in 64bit (Int64 and UInt64) ? See, the idea of being typed by a modifier after the "=" for numerical constant is disturbing me. Share this post Link to post
DelphiUdIT 176 Posted February 15 (edited) 43 minutes ago, Kas Ob. said: It would be great if you or anyone shared these warnings, i only can imagine what could be the case(s), but still when and where the compiler draw the line for such runtime evaluations yet it does accept them at compile time Edited February 15 by DelphiUdIT 1 Share this post Link to post
DelphiUdIT 176 Posted February 15 LOOOL, every time is an improvement ... Share this post Link to post
DelphiUdIT 176 Posted February 15 (edited) HOW TO DO IT ? Insert this in the code: {$WARN BOUNDS_ERROR ERROR} Refer to: https://docwiki.embarcadero.com/RADStudio/Athens/en/Warning_messages_(Delphi) P.S.: by now this will be a standard directive in all my code Edited February 15 by DelphiUdIT Share this post Link to post
Remy Lebeau 1394 Posted February 15 9 hours ago, Kas Ob. said: This inconsistency is very annoying with Delphi compiler, and as you see it, untyped constant should be ... well .... untyped , duh ! , its value i mean in this case numerical value used as needed and casted in place of usage. CW_USEDEFAULT is actually typed as 'int' in the Windows SDK (in winuser.h): #define CW_USEDEFAULT ((int)0x80000000) Share this post Link to post
Kas Ob. 121 Posted February 16 12 hours ago, Remy Lebeau said: CW_USEDEFAULT is actually typed as 'int' in the Windows SDK (in winuser.h): Right. Microsoft define its literals strictly in most cases, yet the compiler has well defined behavior, both for the best outcome from using the SDK. Look at this no problem and no warning. Here the compiler warns but compile, and the IDE didn't show anything different for the other DWORD and INT32 But here with lets say HANDLE Things are very different, as HANDLE are defined as struct as you know, specially to prevent the code from doing constant assignment. Like this Now why it is an integer: i think because it had been misunderstood as very big value (not the biggest though 0x80000000) instead of lowest possible negative value in 32bit, it could simply been declared as -1 and called a day, but who knows might be some legacy issue. Share this post Link to post