2016-10-08 17:33:00 +0200, Conrad Hoffmann:
[...]
>   $ TEST=5; echo $((--TEST+++3)) # outputs 7
> 
> However, due to the documented operator precedence, I would have
> expected that expression to be equal to:
> 
>   $ TEST=5; echo $((--(TEST++)+3)) # outputs 8
> 
> Instead, though, it seems to be equal this one:
> 
>   $ TEST=5; echo $(((--TEST)+++3)) # outputs 7
> 
> So my qestions are:
> 
> Is this a bug? Or is this something that can't be resolved due
> ambiguities in the grammar? Or what's going on here at all?
[...]

--, ++ are optional in POSIX. That means you can't use those
operators in POSIX scripts and that if you need to combine two
unary - or + or a binary - with a unary -, you need to use
spaces or paren:

$((1--1)) # unspecified
$((--1)) # unspecified
$((--var)) # unspecified
$((1 - -1)) # OK
$((- -1)) # OK
$((1-(-1))) # OK
$((-(-1))) # OK

Now, if we look at the C spec, the way +++ is parsed is down to
tokenisation that will also go for the longest operator first.

There --test+++3 would be tokenised as -- test ++ + 3 which
would lead to a syntax error as test++ isn't an lvalue.

bash works differently.

>From what I understand from past discussions on the subject here
bash doesn't treat it as a syntax error and tries instead to tokenise
those incorrect ++/-- into multiple + or - operators if possible.

So here, --TEST+++3 is:

--TEST + +(+3)

And --(TEST++)+3

would be: -(-(TEST++))+3

-- 
Stephane

Reply via email to