PowerShell: Compound assignment operators don't obey StrictMode in dynamic scope

Prerequisites

Steps to reproduce

Continued discussion from https://github.com/PowerShell/PowerShell/issues/17911

Compound assignment operators (e.g. +=, -=, *=) behave weirdly when operating on non-existent variables in dynamic scope, e.g. functions. This is even when using Set-StrictMode -Version 3.0 which does protect against most other undefined variable uses:

> Set-StrictMode -Version 3.0
> function Test-Increment { $x++; $x }
> Test-Increment
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.

> function Test-Assign { $x = $x + 1; $x }
> Test-Assign
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.

> function Test-CompoundAssign { $x += 1; $x }
> Test-CompoundAssign
1

Do note that it only happens in dynamic scope, as in regular prompt all of those statements are caught:

> $x++; $x
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.
dkaszews@Cuddles-Berry:~/Downloads

> $x = $x + 1; $x
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.

> $x += 1; $x
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.

Expected behavior

> function Test-CompoundAssign { $x += 1; $x }
> Test-CompoundAssign
InvalidOperation: The variable '$x' cannot be retrieved because it has not been set.

Actual behavior

> function Test-CompoundAssign { $x += 1; $x }
> Test-CompoundAssign
1

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.3.0-preview.3
PSEdition                      Core
GitCommitId                    7.3.0-preview.3-304-gd02c59addc24e13da3b8ee5e1a8e7aa27e00c745
OS                             Linux 5.15.0-1013-raspi #15-Ubuntu SMP PREEMPT Mon Aug 8 06:33:06 UTC 2022
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 1
  • Comments: 17 (11 by maintainers)

Most upvoted comments

Proposed solution is to create a new Set-StrictMode -Version 4.0 to avoid any breaking changes.

I do also want to note that this isn’t exactly the easy solution it seems to be off the bat. Every time a new version is added, it splinters into a new dialect which needs to be tested separately. It’s a high maintenance burden that needs significant value-add to be considered.