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'.