Lazarus

Free Pascal => General => Topic started by: MarkMLl on July 31, 2021, 12:26:43 pm

Title: Checking compiler mode
Post by: MarkMLl on July 31, 2021, 12:26:43 pm
Is there a compile-time check which will show whether the current mode is one in which the mod operator will work in accordance with the ISO Pascal definition?

I'm aware of -Miso and {$modeswitch ISOMOD } , but at a particular place in the code I want to know whether one of these is active and if not use a custom operator:

Code: Pascal  [Select][+][-]
  1. (* "Number theory compatible" implementation of the modulo operator, hopefully
  2.   to match the Python operator's characterisitics.
  3. *)
  4. operator >< (a, b: int64): int64;
  5.  
  6. (* See https://forum.lazarus.freepascal.org/index.php/topic,48549.msg349691.html#msg349691 *)
  7. (* In principle $modeswitch ISOMOD should fix the problem, but I don't know     *)
  8. (* what version of the compiler introduced it (I suspect later than 3.0.4).     *)
  9.  
  10. begin
  11.   Result := abs(a) mod abs(b);
  12.   if (a < 0) and (Result<>0) then
  13.     Result := abs(b) - Result
  14. end { >< } ;
  15.  

MarkMLl
Title: Re: Checking compiler mode
Post by: Kays on July 31, 2021, 12:44:02 pm
Is there a compile-time check which will show whether the current mode is one in which the mod operator will work in accordance with the ISO Pascal definition?
No. As you probably already know, the {$ifOpt} (https://freepascal.org/docs-html/current/prog/progsu33.html) directive only works on settings a short/single-letter alternative exists for.

I'm aware of -Miso and {$modeswitch ISOMOD } , but at a particular place in the code I want to know whether one of these is active and if not use a custom operator: […]
Simply always use the “custom” operator. Write a separate unit in which you “overload”, for instance, the >< operator in any case, yet this unit has {$modeSwitch ISOMod+} at the top.
Code: Pascal  [Select][+][-]
  1. unit foo;
  2. {$modeSwitch ISOMod+}
  3. {$modeSwitch result+}
  4. interface
  5.   operator >< (const x: ALUSint; const y: ALUUint): ALUUInt;
  6. implementation
  7.   operator >< (const x: ALUSint; const y: ALUUint): ALUUInt;
  8.     begin
  9.       result := x mod y;
  10.     end;
  11. end.
The unit can be compiled in any compiler compatibility mode (that supports units and operator overloading), but will always use an ISO-compliant definition of mod.

The ISO-compliant definition of mod exists for almost ten years now (https://gitlab.com/freepascal.org/fpc/testconversion/-/commit/38db7ba22b13d277fae6b160a84c4d68f9d1bfa2), basically since {$mode ISO} was supported in 2.6.0 (https://wiki.freepascal.org/FPC_New_Features_2.6.0#Basic_ISO_Standard_Pascal_support). The {$modeSwitch ISOMod+}, however, exists for over 5 years now (https://gitlab.com/freepascal.org/fpc/testconversion/-/commit/62e9c1a42c76a0b2a78fae31b5cb56e9a7721b86). It was not available in 3.0.0. The most recent git test conversion stops tagging at 3.0.0RC1, so I can’t make any definite statement, whether it was available in 3.0.4.
Title: Re: Checking compiler mode
Post by: PascalDragon on August 01, 2021, 01:05:18 pm
Is there a compile-time check which will show whether the current mode is one in which the mod operator will work in accordance with the ISO Pascal definition?

The current mode of the unit is available as FPC_<mode> define. Modeswitches themselves have no defines however (so you would not be able to detect {$MODE ISO}{$MODESWITCH ISOMOD-}.
Title: Re: Checking compiler mode
Post by: MarkMLl on August 01, 2021, 02:56:10 pm
Is there a compile-time check which will show whether the current mode is one in which the mod operator will work in accordance with the ISO Pascal definition?

The current mode of the unit is available as FPC_<mode> define. Modeswitches themselves have no defines however (so you would not be able to detect {$MODE ISO}{$MODESWITCH ISOMOD-}.

Thanks for that, still useful.

MarkMLl
TinyPortal © 2005-2018