Discussion:
[ast-developers] Regression incrementing uninitialized integer array elements.
Dan Douglas
2014-05-26 07:10:45 UTC
Permalink
Hi,

When I increment an uninitialized element of an indexed or associative array
from within an arithmetic context, there is no effect in the latest alpha. It
worked in ksh93u. It applies only to arithmetic assignments, but incrementing
via simple assignment works fine.

Can anyone reproduce this regression?

$ ksh -c 'print -v .sh.version'
Version AIJM 93v- 2014-05-09

# Increment from math context broken.
$ ksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
typeset -a -l -i arr=()
typeset -l -i i=1

# Simple assignments are fine.
$ ksh -c 'integer i; integer -a arr; i+=1 arr[3]+=1; typeset -p arr i'
typeset -a -l -i arr=([3]=1)
typeset -l -i i=1

# Compound assignments also fine.
$ ksh -c 'integer -a arr; arr+=([3]+=1); typeset -p arr'
typeset -a -l -i arr=([3]=1)

# First example in mksh/zsh.
$ mksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
set -A arr
typeset -i arr[3]=1
typeset -i i=1

$ zsh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
zsh:1: bad option: -a
typeset -a arr
arr=('' '' 1)
typeset -i i=1
--
Dan Douglas
Dan Douglas
2014-05-26 07:10:45 UTC
Permalink
Hi,

When I increment an uninitialized element of an indexed or associative array
from within an arithmetic context, there is no effect in the latest alpha. It
worked in ksh93u. It applies only to arithmetic assignments, but incrementing
via simple assignment works fine.

Can anyone reproduce this regression?

$ ksh -c 'print -v .sh.version'
Version AIJM 93v- 2014-05-09

# Increment from math context broken.
$ ksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
typeset -a -l -i arr=()
typeset -l -i i=1

# Simple assignments are fine.
$ ksh -c 'integer i; integer -a arr; i+=1 arr[3]+=1; typeset -p arr i'
typeset -a -l -i arr=([3]=1)
typeset -l -i i=1

# Compound assignments also fine.
$ ksh -c 'integer -a arr; arr+=([3]+=1); typeset -p arr'
typeset -a -l -i arr=([3]=1)

# First example in mksh/zsh.
$ mksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
set -A arr
typeset -i arr[3]=1
typeset -i i=1

$ zsh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
zsh:1: bad option: -a
typeset -a arr
arr=('' '' 1)
typeset -i i=1
--
Dan Douglas
Henk Langeveld
2014-05-26 11:15:55 UTC
Permalink
My observation below...

On 05/26/2014 09:10 AM, Dan Douglas wrote:> Hi,
Post by Dan Douglas
When I increment an uninitialized element of an indexed or associative array
from within an arithmetic context, there is no effect in the latest alpha. It
worked in ksh93u. It applies only to arithmetic assignments, but incrementing
via simple assignment works fine.
Can anyone reproduce this regression?
$ ksh -c 'print -v .sh.version'
Version AIJM 93v- 2014-05-09
# Increment from math context broken.
$ ksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
typeset -a -l -i arr=()
typeset -l -i i=1
There are two things at work here.

One: we're working with unitialised variables. What do the standards
actually say about this? (I will be looking this up).

Two: The regression appears to be constrained to 'typeset -p', which I'm
unlikely to use in a script.

Here's my output. Note that if I uncomment the 'set -e -u' in line [5],
the script does not proceed past [9]:

[5]:~/src/ksh-regression 74 $ PS4='+[$LINENO] '
../ast/arch/linux.i386\-64/bi>
Version AIJM 93v- 2014-01-14
+[5] : set -e -u
+[6] typeset -li i
+[7] typeset -li -a arr
+[8] ((i++))
+[9] ((arr[3]++))
+[10] test 1 -eq 1
+[11] test 1 -eq 1
+[12] : '${arr[3]}=1' expects 1
+[13] typeset -p arr
typeset -a -l -i arr=()

Note how typeset -p appears to contradict the results
of lines [11] and [12].

And here's the code for easy copy/paste:

print -v .sh.version

function increment_from_math_context {
: set -e -u
integer i
integer -a arr
((i++))
((arr[3]++)) # Fails when -u set
(test ${arr[3]} -eq 1)
(test ${i} -eq 1)
: '${arr[3]}'=${arr[3]} expects 1
typeset -p arr
}

typeset -tf increment_from_math_context
increment_from_math_context
Dan Douglas
2014-05-26 12:36:09 UTC
Permalink
Post by Henk Langeveld
My observation below...
On 05/26/2014 09:10 AM, Dan Douglas wrote:> Hi,
Post by Dan Douglas
When I increment an uninitialized element of an indexed or associative array
from within an arithmetic context, there is no effect in the latest alpha. It
worked in ksh93u. It applies only to arithmetic assignments, but incrementing
via simple assignment works fine.
Can anyone reproduce this regression?
$ ksh -c 'print -v .sh.version'
Version AIJM 93v- 2014-05-09
# Increment from math context broken.
$ ksh -c 'integer i; integer -a arr; ((i++, arr[3]++)); typeset -p arr i'
typeset -a -l -i arr=()
typeset -l -i i=1
There are two things at work here.
One: we're working with unitialised variables. What do the standards
actually say about this? (I will be looking this up).
POSIX doesn't say anything about the integer attribute and doesn't require the
pre/post increment operators. However:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_01_02_01

"All variables shall be initialized to zero if they are not otherwise assigned
by the input to the application."

Not to mention consistency with the rest of the language and all the other
implementations.
Post by Henk Langeveld
Two: The regression appears to be constrained to 'typeset -p', which I'm
unlikely to use in a script.
Interesting. I don't usually use it in scripts either but it's invaluable for
testing/debugging IMO. print -C (or printf '%#B') is also affected (which is
much more useful in scripts):

$ ksh <<\EOF
Post by Henk Langeveld
integer -a arr
((arr[3]++))
printf "<%s> " "$(print -v arr[3])" "$(print -C arr)" "$(typeset -p arr)" "${arr[3]}" $((arr[3]))
echo
EOF
<1> <> <typeset -a -l -i arr=()> <1> <1>
--
Dan Douglas
Henk Langeveld
2014-05-26 13:32:10 UTC
Permalink
Post by Dan Douglas
Post by Henk Langeveld
One: we're working with unitialised variables. What do the standards
actually say about this? (I will be looking this up).
POSIX doesn't say anything about the integer attribute and doesn't require the
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_01_02_01
"All variables shall be initialized to zero if they are not otherwise assigned
by the input to the application."
That's rather vague wording from section 1.1, "Relation to other
documents". Vague, as the POSIX shell has no concept of integers.
Post by Dan Douglas
Not to mention consistency with the rest of the language and all the other
implementations.
Post by Henk Langeveld
Two: The regression appears to be constrained to 'typeset -p', which I'm
unlikely to use in a script.
Interesting. I don't usually use it in scripts either but it's invaluable for
testing/debugging IMO. print -C (or printf '%#B') is also affected (which is
$ ksh <<\EOF
Post by Henk Langeveld
integer -a arr
((arr[3]++))
printf "<%s> " "$(print -v arr[3])" "$(print -C arr)" "$(typeset -p arr)" "${arr[3]}" $((arr[3]))
echo
EOF
<1> <> <typeset -a -l -i arr=()> <1> <1>
I found similar issues with print [-v | -C].

It looks like that part of print shares code with typeset -p. Something
to do with discovering the contents of a non-simple variable.
Definitely present since January (the last ast download I've got here).

Cheers,
Henk

Loading...