Re: arithmetic problem, incorrect return code with ((var++)) when var is 0 before operation

2017-04-22 Thread Eduardo Bustamante
On Sat, Apr 22, 2017 at 12:49 PM, Andrew McGlashan
 wrote:
[...]
>
> The return code from ((i++)) operation is different when i has an
> initial value of 0.

This is not a bug.

Please read the Bash reference manual section on conditional
constructs: 
https://www.gnu.org/software/bash/manual/bash.html#index-commands_002c-conditional

| The arithmetic expression is evaluated according to the rules
described below (see Shell Arithmetic). If the value of the expression
is non-zero, the return status is 0; otherwise the return status is 1.
This is exactly equivalent to
|
| let "expression"

This is also described in other sources:

1. http://wiki.bash-hackers.org/commands/builtin/let#description
2. http://mywiki.wooledge.org/ArithmeticExpression#Arithmetic_Commands

Also see the 1st example in http://mywiki.wooledge.org/BashFAQ/105
("Why doesn't set -e (or set -o errexit, or trap ERR) do what I
expected?"), which mentions this pitfall.

You can also find extensive discussions in the bug-bash archives on
why you shouldn't be using set -e, regardless of how many "sources" on
the web claim that it helps write "robust" or "correct" shell scripts.



arithmetic problem, incorrect return code with ((var++)) when var is 0 before operation

2017-04-22 Thread Andrew McGlashan
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash'
-DSHELL -DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib
-Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat
-Werror=format-security -Wall
uname output: Linux andrewm-Satellite-P50-A 4.4.0-72-generic #93-Ubuntu
SMP Fri Mar 31 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.3
Patch Level: 42
Release Status: release

Description:

The return code from ((i++)) operation is different when i has an
initial value of 0.

This problem was discovered when running run a bash script with "set
-ue" and having "((i++))" as the last command in a loop.


Repeat-By:

The following script will quit with an error after the first iteration
due to the return code errantly being 1.

#!/bin/bash
set -eu
i=0
for a in a b c
do
   echo "${a}"
   ((i++))
done


NB: If i starts as 1, the script works as expected.

Also, using ((i+=1)) works fine, but I prefer the ((i++)) format.


Proof outside a loop:

$ c=0;((c++));echo $?
1


$ c=1;((c++));echo $?
0