question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compound assignment operators don't obey StrictMode in dynamic scope

See original GitHub issue

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

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:16 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
SeeminglySciencecommented, Oct 17, 2022

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.

0reactions
daxian-dbwcommented, Nov 18, 2022

@dkaszews Sorry that I missed your last comment.

Here is a quick search of Set-StrictMode -Version latest in GitHub: https://grep.app/search?q=Set-StrictMode -Version latest. You can take a look and see how much it’s used.

I know the doc called out the caveat of using Latest, and yeah according to the behavior we defined in the doc, whoever uses latest opts into receiving stricter rules. But they will find stuff stop working when upgrading to a new PS version, so it’s still practically a breaking change.

I’m not saying any breaking change is a hard big NO. It will need closer look from the team to weigh the value and cost.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Dynamic variable scope is broken for += · Issue #17911
Dynamic variable scope is broken for += #17911 ... Compound assignment operators don't obey StrictMode in dynamic scope #17959.
Read more >
Why don't Java's compound assignment operators require ...
The Problem When you assign two variables with different primitive types – for example long to int – you need to use casting....
Read more >
Template type checking
TypeScript checks the assignment according to its type system, obeying flags such as strictNullChecks as they are configured in the application. Avoid run-time ......
Read more >
about Assignment Operators - PowerShell
Compound assignment operators don't use dynamic scoping. The variable is always in the current scope. In the following example, the variable $x ...
Read more >
Google JavaScript Style Guide
1 Introduction. This document serves as the complete definition of Google's coding standards for source code in the JavaScript programming language.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found