GNAT 15: (style) redundant parentheses [-gnatyz]

asn1scc generated code includes the adasn1rtl.ads file, which contains this:

   function Asn1Real_Equal (Left, Right : Asn1Real) return Boolean is
     (if Left = Right then True elsif Left = 0.0 then Right = 0.0
      elsif (Left > 0.0 and Right < 0.0) or (Left < 0.0 and Right > 0.0) then
        False
      elsif abs (Left) > abs (Right) then abs (Right) / abs (Left) >= 0.99999
      else abs (Left) / abs (Right) >= 0.99999);

GNAT 15.2.0 complains about the parentheses around abs

 /usr/local/gnat15/bin/gcc -c -x ada -gnatA -gnatwae -gnat2012 -g -gnatf -gnaty -gnatwa -gnatg -fstack-check -g -O0 -gnatwe -gnatwa -gnat2012 -gnatec=/tmp/GPR.64851/GNAT-TEMP-000003.TMP -gnatem=/tmp/GPR.64851/GNAT-TEMP-000004.TMP mainprogram.adb
adaasn1rtl.ads:94:17: (style) redundant parentheses [-gnatyz]
adaasn1rtl.ads:94:30: (style) redundant parentheses [-gnatyz]
adaasn1rtl.ads:94:47: (style) redundant parentheses [-gnatyz]
adaasn1rtl.ads:94:61: (style) redundant parentheses [-gnatyz]
adaasn1rtl.ads:95:16: (style) redundant parentheses [-gnatyz]
adaasn1rtl.ads:95:29: (style) redundant parentheses [-gnatyz]

why? it was ok under GNAT 14

I find it personally more readable with the parentheses.

Why not just turn the warning off if you don’t care about it?

It looks like this is where it came from:

With rationale being:

GNAT already emits a style warning when redundant parentheses appear inside
logical and short-circuit operators. A similar warning will be soon emitted for
unary operators as well. This patch removes the redundant parentheses to avoid
build errors.

I’d probably end up doing something like this for readability:

   function Asn1Real_Equal (Left, Right : Asn1Real)
   return
      Boolean
   is
      (if Left = Right then
         True
       elsif Left = 0.0 then
         Right = 0.0
       elsif
         Left > 0.0 and Right < 0.0 or
         Left < 0.0 and Right > 0.0
       then
         False
       elsif abs (Left) > abs (Right) then
         abs (Right) / abs (Left) >= 0.99999
       else
         abs (Left) / abs (Right) >= 0.99999);

Barnes 2022 writes,

However, although the precedences are equal, and, or and xor cannot be mixed up in an expression without using parentheses (unlike + and - for instance).

indeed this gives

error: mixed logical operators in expression

AdaRM allows repeating

simple_expression ::= [unary_adding_operator] term {binary_adding_operator term}

but not

expression ::=
relation {and relation} | relation {and then relation}
| relation {or relation} | relation {or else relation}
| relation {xor relation}

EDIT I clearly haven’t had enough coffee and it’s impacting my reading comprehension, I just realized that it’s complaining about using them around abs. Just disregard my response. I’ll leave my posts up as a monument to my shame.

No worries, we are all learning here. Your answer actually made me look up Ada RM, something I should be doing more often.

Now I understand that we have a concept of highest preference operators and therefore abs not and ** need no parentheses. Thank you.

No operators need parenthesis unless association is forbidden. E.g. in A + -B or 1 ** +2.

Precedence plays little role. Example: 1*-2 is illegal.

Side note: when building the bare_runtime crate using gnat15 you also have to remove all of the redundant parentheses since style warnings are treated as errors for runtime systems. Guess how I know :upside_down_face:

I would guess Ada does better here but I never rely on precedence (since before the Linux kernel rules added that you shouldn’t) which can be the cause of bugs through unnecessary complexity. I remove them when the Gnat compiler assures me it’s all good though with some knee jerk annoyance that’s fading.