[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a
From: |
Chet Ramey |
Subject: |
Re: Possible bug in 4.3.11: Nameconflict when when passing an array to a function |
Date: |
Wed, 28 Oct 2015 11:57:24 -0400 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 |
On 10/28/15 10:22 AM, Greg Wooledge wrote:
> Now, as for the changes from bash 4.2 to 4.3, I don't know the whole
> answer. Here are some of the changes from the CHANGES file:
>
> u. There are changes to the expansions peformed on compound array
> assignments,
> in an effort to make foo=( [ind1]=bar [ind2]=baz ) identical to
> foo[ind1]=bar foo[ind2]=baz.
>
> hhhh. Fixed a bug that caused `declare' and `test' to find variables that
> had been given attributes but not assigned values. Such variables are
> not set.
Posix has introduced, and bash implements, the concept of a `declaration
command'. This basically means that there are several builtins that
accept assignment statements as arguments and that those builtins should
expand the RHS of the assignment statement as if the assignment statement
stood alone
http://austingroupbugs.net/view.php?id=351
Now, to make this work correctly, something like local -i foo=expression
needs to be treated like
local -i foo; foo=expression
The variable needs to be created with the correct attributes in the cases
that those attributes affect how the assignment is expanded. The array
attribute is one of those cases.
The second point that Greg includes above is important. The shell
considers a variable to be set only if it has been assigned a value.
Creating a `placeholder' variable with attributes results in a variable
that is technically unset until an assignment to it is performed.
In your example, because you shadow a global variable with a local
variable, you run into a conflict with these features.
Your example becomes -- internally -- equivalent to
local -a arr; arr=( "${!1}" )
which is expanded to
local -a arr; arr=( "${arr[@]}" )
(which, as Greg points out, is too clever by half).
So the expansion on the rhs of the assignment statement finds the closest
variable in scope, which is the (techically unset) local variable. This is
the sketchiest part of the current implementation. In most cases, you want
the local variable when you reference it in a shell function, but this is
one where you do not.
Anyway, finding the local unset variable results in a null value, which
gets assigned to the local array variable.
Omitting the -a results in the creation of a local variable, but that
appears to have sequencing problems. I'll have to take a look at that part.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU chet@case.edu http://cnswww.cns.cwru.edu/~chet/