Path: csiph.com!xmission!news.snarked.org!news.linkpendium.com!news.linkpendium.com!panix!usenet.stanford.edu!not-for-mail From: L A Walsh Newsgroups: gnu.bash.bug Subject: Re: expression evaluation problem Date: Wed, 24 Jul 2019 11:43:11 -0700 Lines: 79 Approved: bug-bash@gnu.org Message-ID: References: <5D3889D2.3090101@tlinx.org> <20190724175103.GN1218@eeg.ccf.org> <5D38A6BF.9020309@tlinx.org> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Trace: usenet.stanford.edu 1563993802 8202 209.51.188.17 (24 Jul 2019 18:43:22 GMT) X-Complaints-To: action@cs.stanford.edu Cc: Greg Wooledge To: bug-bash Envelope-to: bug-bash@gnu.org User-Agent: Thunderbird In-Reply-To: <20190724175103.GN1218@eeg.ccf.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 173.164.175.65 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: <5D38A6BF.9020309@tlinx.org> X-Mailman-Original-References: <5D3889D2.3090101@tlinx.org> <20190724175103.GN1218@eeg.ccf.org> Xref: csiph.com gnu.bash.bug:15237 On 2019/07/24 10:51, Greg Wooledge wrote: > 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. > Those aren't my variables. If you assign the integer attribute to a variable it isn't the same as when you don't. > >> # 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". > --- Why? It isn't even necessary when 'c' is greater than 'uxtra' > Only then does the arithmetic evaluation begin. > ---- Perhaps that such evaluate happens outside of normal evaluation rules is why shell is so slow? > 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. > That's because it is a fragment from a program. It was the minimum from that program to reproduce the problem. It's supposed to assign 960 to 'v'. 'v' is for 'value'. 'c' is an integer counter. uxtra is a limit. > Have you considered performing your calculation in steps, with > intermediate values stored in temporary variables with clear names? > That greatly improves readability. > --- Does it improve execution time? That's more of a concern here than readability, since it is an expression fragment, it isn't meant to be understood in isolation. More to the point, how do I get evaluation to occur in arithmetic order? I.e. so the string operation is done in the order the expression is evaluated? > 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. > The important part for me is whether or not it is faster to perform 1 calculation, or 100. So which would be faster? In this case execution speed is more important than clarity. I consider that a 'constraint'.