bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: $(( )): binary/unary VAR/NUM inconsistency


From: Steffen Nurpmeso
Subject: Re: $(( )): binary/unary VAR/NUM inconsistency
Date: Thu, 07 Jul 2022 18:11:23 +0200
User-agent: s-nail v14.9.24-268-g937248580b

Hello!

Chet Ramey wrote in
 <1d592238-69c5-88b6-6e08-5d56e3170216@case.edu>:
 |On 7/6/22 1:10 PM, Steffen Nurpmeso wrote:
 ...
 |> I stumbled upon this (bash 5.1.16); i find it "understandable" in
 |> respect to clarity, but inconsistent, and also in hindsight to the
 ...
 |Thanks for the report. Most of these are due to bash trying to be helpful.
 |The pre/postfix operators are parsed as such when they make sense depending
 |on what precedes or follows them. For instance, if you have ++I, it's
 |parsed as a pre-increment; if you have ++1, it's parsed as two unary plus
 |operators and an integer constant.
 |
 |(Part of this was an attempt to be backwards compatible when I added the
 |++ and -- operators, since they weren't present until bash-2.04.)
 |
 |> 
 |>    $ bash -c 'I=10;echo "<$(( +10+++I ))>"'
 |>    <21>
 |
 |unary plus, constant, binary plus operator, pre-increment, variable
 |
 |>    $ bash -c 'I=10;echo "<$(( +10+ ++I ))>"'
 |>    <21>
 |
 |same
 |
 |>    $ bash -c 'I=10;echo "<$(( +10+ +I ))>"'
 |>    <20>
 |
 |unary plus, constant, binary plus operator, unary plus, variable

Funnily my parser has only one (what i know) problem left, the
same as bash.  On the other hand i found more.

[
    # make this work with (ba)sh \
    command -v shopt && shopt -s expand_aliases;\
    alias p=printf;alias e=echo;alias s=export
    #
    s I=10 J=33
]

  e "<$((  3          +           (      11       )  ))>"
  s I=10 J=33;p "<$(( +10 + + +I ))>";e "<$I>"
  s I=10 J=33;p "<$(( +10 + ++I ))>";e "<$I>"
  s I=10 J=33;p "<$(( +10 ++ +I ))>";e "<$I>"
  s I=10 J=33;p "<$(( +10 +++ I ))>";e "<$I>"
  s I=10 J=33;p "<$(( +10+++I ))>";e "<$I>"

And diff -u10 OUT .nail/y/t.wysh-arith-good

   <14>
   <20><10>
   <21><11>
   <20><10>
  -<21><11>
  +<20><10>
   <21><11>

I find bash less consistent, my thought was "either whitespace
matters, then it matters, or not".  (My first version removed
_all_ whitespace before parsing started, which was a failure.) 

And one more thing.

  -<802379605485813759>
  +<9223372036854775807>

This is from 

  $ bash -c 'echo $((999999999999999999999999999999999999999999999))'
  802379605485813759
  $ dash -c 'echo $((999999999999999999999999999999999999999999999))'
  9223372036854775807
  $ busybox.static sh -c \
    'echo $((999999999999999999999999999999999999999999999))'
  0
  $ MXEXE -#:/ \
    -Y 'echo $((999999999999999999999999999999999999999999999))' \
    -Yx
  9223372036854775807

(But

  $ bash -c 'echo $((0x8000000000000000))'
  -9223372036854775808
  $ dash -c 'echo $((0x8000000000000000))'
  9223372036854775807
  $ busybox.static sh -c 'echo $((0x8000000000000000))'
  -9223372036854775808
  $ MXEXE -#:/ -Y 'echo $((0x8000000000000000));x'
  -9223372036854775808

and

  $ MXEXE -#:/ -Y 'echo $((0xFFFFFFFFFFFFFFFF));x'
  -1
  $ dash -c 'echo $((0xFFFFFFFFFFFFFFFF))'
  9223372036854775807
  $ bash -c 'echo $((0xFFFFFFFFFFFFFFFF))'
  -1
  $ busybox.static sh -c 'echo $((0xFFFFFFFFFFFFFFFF))'
  -1

and

  $ busybox.static sh -c 'echo $((0xFFFFFFFFFFFFFFFF1))'
  0
  $ bash -c 'echo $((0xFFFFFFFFFFFFFFFF1))'
  -15
  $ dash -c 'echo $((0xFFFFFFFFFFFFFFFF1))'
  9223372036854775807
  $ MXEXE -#:/ -Y 'echo $((0xFFFFFFFFFFFFFFFF1));x'
  9223372036854775807

bash explicitly documents "no overflow checking", and things are
very wild in general.  My thoughts were 64-bit signed integer, but
for known power-of-two bases, which are parsed as unsigned, then
stored as signed 64-bit.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]