Bug 218943

Summary: /bin/sh regression? with doubly negated numbers
Product: Base System Reporter: John Hein <jcfyecrayz>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed Works As Intended    
Severity: Affects Some People CC: jilles
Priority: ---    
Version: 11.0-STABLE   
Hardware: Any   
OS: Any   

Description John Hein 2017-04-28 20:44:25 UTC
/bin/sh has changed behavior on handling doubly (or more) negated numbers:

sh -c 'var=--123; echo $(($var))'

Under FreeBSD 9 and earlier, it "works":

123


Under 10 & 11:

sh: arithmetic expression: expecting primary: "--123"

I'm trying to find the posix stance on this.  Please add a note here if you know where posix would weigh in on that kind of arithmetic expression.
Comment 1 Jilles Tjoelker freebsd_committer freebsd_triage 2017-04-29 14:18:34 UTC
The behaviour indeed changed, deliberately.

What POSIX intends exactly may not be fully clear (see discussion on the Austin Group mailing list in March 2017), but it states that -- and ++ need not be supported. That is, they may be supported and $((--a)) may decrement a and expand to the decremented value.

In order to avoid ambiguity, I changed sh such that it recognizes the -- and ++ tokens (following C's "maximal munch" rule) and reject them.

If you want two minus signs in sequence, separate them with a space or use parentheses.
Comment 2 John Hein 2017-04-30 20:20:00 UTC
I see.

Not that bash is necessarily a good model to follow, but it supports the --/++ operators and is able to distinguish between the context when it's an operator and a double negation.

% bash -c 'var=--123; echo $(($var)); echo $((--var))'
123
122
% bash -c 'echo $((--123))'
123

Same with/without POSIXLY_CORRECT.

But thanks for the explanation.  Closing this as 'works as intended'.  I guess sh(1) could be enhanced to distinguish - from context - between the operator and a double negation (and only throw the error for the former case).  I'm sure it's quite tricky.
Comment 3 Jilles Tjoelker freebsd_committer freebsd_triage 2017-04-30 21:52:34 UTC
I know what bash does but I don't think trying as hard as possible to get a valid parse is helpful.