Path: csiph.com!goblin1!goblin.stu.neva.ru!usenet.stanford.edu!not-for-mail From: Greg Wooledge Newsgroups: gnu.bash.bug Subject: Re: expression evaluation problem Date: Wed, 24 Jul 2019 13:51:03 -0400 Lines: 41 Approved: bug-bash@gnu.org Message-ID: References: <5D3889D2.3090101@tlinx.org> <20190724175103.GN1218@eeg.ccf.org> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: usenet.stanford.edu 1563990709 6600 209.51.188.17 (24 Jul 2019 17:51:49 GMT) X-Complaints-To: action@cs.stanford.edu Cc: bug-bash To: L A Walsh Envelope-to: bug-bash@gnu.org Mail-Followup-To: L A Walsh , bug-bash Content-Disposition: inline In-Reply-To: <5D3889D2.3090101@tlinx.org> User-Agent: Mutt/1.10.1 (2018-07-13) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 139.137.100.1 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <20190724175103.GN1218@eeg.ccf.org> X-Mailman-Original-References: <5D3889D2.3090101@tlinx.org> Xref: csiph.com gnu.bash.bug:15233 On Wed, Jul 24, 2019 at 09:39:46AM -0700, L A Walsh wrote: > str='cf80' > v=960 uxtra=1 c=0 Irrelevant alias shenanigans omitted. These are your variables. > # In evaluating this expression: > ((v = v | ( uxtra>=++c ? ((0x${str:2*c:2}) & 63) << (6*(uxtra-c)) : 0 ))) > > > I get 985 and not 960 as expected > > Which only happens when 'c' is 0 in the middle 'str' expression, > but the ++c should increment 'c' to '1' before it is tested to be > less than or equal to 'uxtra'(=1). The ${str:2*c:2} part is performed first, while c is still 0, and it expands to "cf". Only then does the arithmetic evaluation begin. wooledg:~$ str='cf80' wooledg:~$ v=960 uxtra=1 c=0 wooledg:~$ ((v = v | ( uxtra>=++c ? ((0xcf) & 63) << (6*(uxtra-c)) : 0 ))) wooledg:~$ declare -p v declare -- v="975" Even with that parameter expansion out of the way, this arithmetic command is still ridiculously over-complicated. I can't even guess what it's supposed to do. Have you considered performing your calculation in steps, with intermediate values stored in temporary variables with clear names? That greatly improves readability. Isolating the ++c into its own step would also remove all questions about whether the increment is performed before or after other calculations (or in this case, parameter expansions). In-lining ++c inside a larger calculation can be OK in very simple situations, but a nightmare to read/understand/debug in more complex cases.