Stephane Chazelas
2014-10-20 20:20:45 UTC
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04
$((a-b)) should work the same as $(($a-$b)) as well.
However, that's not the case for values of $b like "-1" in all the
shells I have tried (yash, zsh, ksh93, mksh, dash, bash, zsh).
In those shells,
a=1 b=-1; "$((a-b))"
is treated as $((1 - -1))
While $(($a-$b)) which is expanded as $((1--1)) is considered as
a syntax error because "--" is treated as the decrementing unary
operator.
I'd argue it's a bug in those shells.
If not, then maybe the standard should make it a requirement
that the "-" and "+" binary operators be surrounded by blank
characters (or braces used) if operands might start with "-" or
"+".
Interestingly. $((1--(1+1))) doesn't fail in bash or dash but
fails in ksh93, zsh, mksh and yash.
GNU and Solaris bc, gawk, mawk, nawk also fail on 1--1 and
1--(1+1)
oawk:
$ awk 'BEGIN{print 1--1;exit}'
10
There's a problem with the "-" unary operator as well:
a=-1; echo "$((-$a))"
fails in everything except dash and bash.
In any case, I suspect the specification for sh, bc and awk
should probably be updated as from my reading, it seems they
only say blanks are ignored and don't make a difference wrt the
meaning of the arithmetic expression, while obviously something
has to be done to be able to disambiguate --x between the unary
-- and the unary - applied twice (so --x vs - -x or -(-x)).
All shells except bash and dash complain on $((1---a))
Some more fun:
$ a=1 dash -c 'echo "$((----a)) $a"'
1 1
$ a=1 bash -c 'echo "$((----a)) $a"'
0 0
$ a=1 zsh -c 'echo "$((----a)) $a"'
-1 -1
More generally I'd argue that saying $(($x)) and $((x)) expand
to the same value is not enough to say how one may use one in
place or the other. For instance $(($x = 2)) would obviously not
work. But would a=foo; : "$(( a = 1 ))" be specified?
If the shell variable x contains a value that forms a valid
integer constant, optionally including a leading plus or
minus sign, then the arithmetic expansions "$((x))" and
"$(($x))" shall return the same value.
* The sizeof() operator and the prefix and postfix "++" and "--"
operators are not required
That would seem to imply thatinteger constant, optionally including a leading plus or
minus sign, then the arithmetic expansions "$((x))" and
"$(($x))" shall return the same value.
* The sizeof() operator and the prefix and postfix "++" and "--"
operators are not required
$((a-b)) should work the same as $(($a-$b)) as well.
However, that's not the case for values of $b like "-1" in all the
shells I have tried (yash, zsh, ksh93, mksh, dash, bash, zsh).
In those shells,
a=1 b=-1; "$((a-b))"
is treated as $((1 - -1))
While $(($a-$b)) which is expanded as $((1--1)) is considered as
a syntax error because "--" is treated as the decrementing unary
operator.
I'd argue it's a bug in those shells.
If not, then maybe the standard should make it a requirement
that the "-" and "+" binary operators be surrounded by blank
characters (or braces used) if operands might start with "-" or
"+".
Interestingly. $((1--(1+1))) doesn't fail in bash or dash but
fails in ksh93, zsh, mksh and yash.
GNU and Solaris bc, gawk, mawk, nawk also fail on 1--1 and
1--(1+1)
oawk:
$ awk 'BEGIN{print 1--1;exit}'
10
There's a problem with the "-" unary operator as well:
a=-1; echo "$((-$a))"
fails in everything except dash and bash.
In any case, I suspect the specification for sh, bc and awk
should probably be updated as from my reading, it seems they
only say blanks are ignored and don't make a difference wrt the
meaning of the arithmetic expression, while obviously something
has to be done to be able to disambiguate --x between the unary
-- and the unary - applied twice (so --x vs - -x or -(-x)).
All shells except bash and dash complain on $((1---a))
Some more fun:
$ a=1 dash -c 'echo "$((----a)) $a"'
1 1
$ a=1 bash -c 'echo "$((----a)) $a"'
0 0
$ a=1 zsh -c 'echo "$((----a)) $a"'
-1 -1
More generally I'd argue that saying $(($x)) and $((x)) expand
to the same value is not enough to say how one may use one in
place or the other. For instance $(($x = 2)) would obviously not
work. But would a=foo; : "$(( a = 1 ))" be specified?
--
Stephane
Stephane