shellcheck icon indicating copy to clipboard operation
shellcheck copied to clipboard

SC2178 not respecting local declaration: Variable was used as an array but is now assigned a string

Open baumanj opened this issue 6 years ago • 3 comments

Despite being declared as local within separate functions, shellcheck complains about a variable being used as both an array and a scalar.

Even if they weren't locally scoped, In this particular case, declaring with -n should obviate this error.

For bugs

  • Rule Id: SC2178
  • My shellcheck version: 0.4.7 on Ubuntu and 0.4.6 on Mac OS
  • [X] I tried on shellcheck.net and verified that this is still a problem on the latest commit

Here's a snippet or screenshot that shows the problem:

#!/bin/bash

f1() {
    local -a var1
    var1[0]=bar
}

f2(){
    # shellcheck disable=2034
    local -n var1=variable_name
}

Here's what shellcheck currently says:

In /tmp/test.sh line 10:
    local -n var1=variable_name
             ^-- SC2178: Variable was used as an array but is now assigned a string.

Here's what I wanted or expected to see:

No error

Workaround

The error disappears if I reorder the references, but I don't think there should be any semantic difference.

#!/bin/bash

f2(){
    local -n var1=variable_name
}

f1() {
    local -a var1
    # shellcheck disable=2034
    var1[0]=bar
}

baumanj avatar May 15 '18 17:05 baumanj

I think this is because the dataflow analysis shellcheck has is not complete. There is an open TODO in the code to make it better. As for the workaround, reordering works because there isn't a check for assigning an array to string :)

ngzhian avatar May 25 '18 05:05 ngzhian

I have another example if scope bleeding across functions (cut 'n pasted from https://www.shellcheck.net/ instead of starting a new issue):

#!/bin/bash

_ekvstore_nonatomic_set () {
  declare -n ns="$1"
  local key="$2"
  local val="$3"

  ns[$key]=$val
}

_ekvstore_nonatomic_rm () {
  declare -n ns="$1"
  local key="$2"

  unset "ns[$key]"
}
$ shellcheck myscript
 
Line 12:
  declare -n ns="$1"
             ^-- SC2034: ns appears unused. Verify use (or export if used externally).
             ^-- SC2178: Variable was used as an array but is now assigned a string.

matthewpersico avatar Apr 11 '19 21:04 matthewpersico

This is another simple example I came across:

#!/bin/bash

f1() {
  local cmd
  cmd=(echo array)
}

f2() {
  local cmd="echo string"
  echo "$cmd"
}

Errors with shellcheck version 0.8.0:

> shellcheck shellcheck_bug_SC2178.sh

In shellcheck_bug_SC2178.sh line 9:
  local cmd="echo string"
        ^-^ SC2178 (warning): Variable was used as an array but is now assigned a string.

In shellcheck_bug_SC2178.sh line 10:
  echo "$cmd"
        ^--^ SC2128 (warning): Expanding an array without an index only gives the first element.

azizk avatar Mar 31 '22 17:03 azizk