Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: arithmetic operator precedence



On 2008-06-17 15:53:38 +0100, Stephane Chazelas wrote:
> On Tue, Jun 17, 2008 at 04:33:57PM +0200, Vincent Lefevre wrote:
> [...]
> > > which I understand as any occurrance of a variable name (other than
> > > $-, $?, $0... obviously) in $((...)) should be the same as if the $
> > > was not ommited (when $x contains an integer constant).
> > 
> > No, POSIX doesn't say that. This sentence is a mean to define the
> > value of x from the contents of $x. But note that parsing has already
> > been done and you have something like a C expression ("The arithmetic
> > expression shall be processed according to the rules given in
> > Arithmetic Precision and Operations"); variables are just replaced
> > by their values, like in C. Without any extension, both interpretations
> > are equivalent anyway.
> 
> That's one interpretation.

And that's the most intuitive one I can see. And that's why both bash
and zsh follow this interpretation.

> [...]
> > Also ** is out of the scope of POSIX too.
> 
> Yes, as I said I think clearly enough, if POSIX were to specify
> ** _in a future version of the standard_,

No, you said: "POSIX does say that $((a ** 2)) is the same as $(($a ** 2))
because $a contains an integer constant, and that's $((-3**2))."

> it is more likely that it implements it as -3 ** 2 == 9, to avoid
> confusion.

That's your opinion. I'd say it is very unlikely to regard
$((a ** 2)) as $(($a ** 2)) because
  1. It is very confusing (more precisely, the $(($a ** 2)) form is
     confusing as far arithmetic evaluation is concerned, and that's
     probably why the form with variables in arithmetic expressions
     have been added).
  2. Several shells (bash, zsh) do it in another way, and AFAIK,
     no-one has complained on their behavior.

> - because it doesn't at the moment clearly state how bare
>   variable names are to be interpreted as you point out (it's true
>   that I was interpreting maybe a bit too much)

As it does a reference to C expressions, I'd say that it should do
like C. Note that with your interpretation, two passes are necessary
if the shell regards advanced forms of integer constants (such as
"1 + 1"): one to identify the variable names, and one to reparse the
expression after replacing the variable names.

> - because it doesn't clearly state whether -3 is an integer
>   constant or not. ash allows a=-3; echo $((a * 3)) while it
>   doesn't allow a=0-3; echo $((a * 3)) for instance. But then,
>   given that a negative number can be the result of an
>   arithmetic expansion, I can't see how it can be interpreted in
>   any other way than -3 is an integer constant.

Yes, that's why it's probably a bug (but POSIX doesn't even say
that the shell should be able to re-read the output value).

> - because all existing shell implementations do it that way at
>   the moment.

Only for precedence reasons (probably without much reflection and
because the unnecessary precedence of the unary - over * was already
there), certainly not because $((a ** 2)) and $(($a ** 2)) are
regarded as the same: they are handled differently.

BTW, when using directed rounding modes, this is very confusing in C.

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)



Messages sorted by: Reverse Date, Date, Thread, Author