Configuration Information [Automatically generated, do not change]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux m41 4.2.0-34-generic #39-Ubuntu SMP Thu Mar 10 22:11:49 UTC 2016 i686 i686 i686 GNU/Linux Machine Type: i686-pc-linux-gnu
Bash Version: 4.3 Patch Level: 42 Release Status: release Description: Odd behaviour when an undefined variable is used in arithemetic expression. ((++F[word]==M)) increments both F[word] AND M But not always. When M is null, M seems to be treated as 0 (as expected) When M is assigned an integer value of an integer associative array element, something goes wrong. (just a guess, since as you will see, this is complex to demonstrate) This can happen when M=1 but usually when M=2. Repeat-By: #!/bin/bash p(){ # print variables printf "F[%s]=[%d] M=[%d] I=[%s]\n" "$1" $((F[$1]*1)) $((M*1)) "$I" } t(){ # iterate - part of a program that counts word frequency and tracks most frequent word p $W # M should not change here ((++F[$W]==M))&&I= # pre-increment F[$W]. If equal to Max then I=NULL p $W # but sometimes, it does! ((F[$W]>M))&&M=F[$W]&&I=$W # if F[$W]>Max then Max=F[$W] p $W } unset F unset X unset M unset W unset I W="word" echo setup # it always fails, but at different iterations! # why does it fail ever????? # an example run # run 3 #+ t #+ p word #+ printf 'F[%s]=[%d] M=[%d] I=[%s]\n' word 2 2 '' # here, M=2 #F[word]=[2] M=[2] I=[] #+ (( ++F[word]==M )) #+ I= #+ p word #+ printf 'F[%s]=[%d] M=[%d] I=[%s]\n' word 3 3 '' # without changing M, it is now 3!!!!!! #F[word]=[3] M=[3] I=[] #+ (( F[word]>M )) #+ p word #+ printf 'F[%s]=[%d] M=[%d] I=[%s]\n' word 3 3 '' #F[word]=[3] M=[3] I=[] #+ set +x # only when setting M from F[$W] or F[word] causes it to fail at iteration 2 declare -iA F; F[word]=1; M=F[word] # fails run 2 #declare -iA F; F[$W]=1; M=F[$W] # fails run 2 # all other ways to initialise M fail at iteration 3 #declare -iA F; declare -iA X; F[$W]=1; X[dog]=1; M=X[dog] # fails run 3 #declare -iA F; declare -iA X; F[$W]=1; X[$W]=1; M=X[$W] # fails run 3 #declare -iA F; F[$W]=1; M=1 # fails run 3 #declare -iA F; F[$W]=1; M="1" # fails run 3 #declare -iA F; F[$W]=1; M=$((1*1)) # fails run 3 #declare -iA F; F[$W]=1; ((M=1)) # fails run 3 #declare -iA F; F[$W]=1; M=${F[$W]} # fails run 3 I=$W p $W echo run 2 t echo run 3 set -x t set +x echo run 4 t Fix: declare -i M This seems to 'fix' this.
dead.bashbug
Description: Binary data