Reconsider version checks in collections?
Many of our mutable collection types maintain version numbers. These version numbers are incremented for many (not necessarily all) of the mutating operations performed on the type, e.g. https://github.com/dotnet/runtime/blob/2ba2396495c22429035d165e478672c442f81e22/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L196-L198 The version number is then snapshot as part of calling GetEnumerator, and every MoveNext on the resulting enumerator compares the version number that was snapshot against the current version number. https://github.com/dotnet/runtime/blob/2ba2396495c22429035d165e478672c442f81e22/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L1166-L1170 This serves as a way to flag some misuse, where mutation is performed during enumeration. The motivation here is good: help developers find misuse. There are a few problems, though: 1. It adds a little overhead. It's minimal, and this alone is not worth a change for, but it requires an extra Int32 field on the type as well as on the enumerator, it requires an increment operation as part of each mutation, and it requires an extra branch as part of each MoveNext. 2. It doesn't cover all forms of enumeration. If, for example, you enumerate a `List<T>` via `foreach (var item in list) Use(item);`, then it applies, but if you change to iterating via `for (int i = 0; i < list.Count; i++) Use(list[i]);`, then it doesn't. 3. We're considering proposals for enabling the compi
Posted by stephentoub on Feb 2, 2023, 3:36 AM
Tags
Related issues
- [Meta] Feedback on granular control over Copilot changes
- unexpected status 401 Unauthorized issue
- [MODEL] Measurable quality regression in Claude generation 5 (Fable 5 / Opus 5 / Sonnet 5): worse nonsense detection, ~2x verbosity, under-disclosed model fallb
- [CRITICAL] Subagent spawning and subagent pattern bugs trigger infinite recursion, infinite token usage, grossly inefficient token usage, and lost accumulated s
- Video stops playing after some minutes
- [MODEL] Claude verbose code comments by default — ignores instructions to stop.
Raise real-world problems, find people facing the same issue, and discuss solutions.2,500 issues0 comments
github (Software)
[Meta] Feedback on granular control over Copilot changes
unexpected status 401 Unauthorized issue
[MODEL] Measurable quality regression in Claude generation 5 (Fable 5 / Opus 5 / Sonnet 5): worse nonsense detection, ~2x verbosity, under-disclosed model fallb
[CRITICAL] Subagent spawning and subagent pattern bugs trigger infinite recursion, infinite token usage, grossly inefficient token usage, and lost accumulated s
Video stops playing after some minutes
[MODEL] Claude verbose code comments by default — ignores instructions to stop.
Scope Codex VS Code chats to the current workspace/project
Update on "Co-authored-by: Copilot" in commit messages
Reconsider version checks in collections?
Many of our mutable collection types maintain version numbers. These version numbers are incremented for many (not necessarily all) of the mutating operations performed on the type, e.g. https://github.com/dotnet/runtime/blob/2ba2396495c22429035d165e478672c442f81e22/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L196-L198 The version number is then snapshot as part of calling GetEnumerator, and every MoveNext on the resulting enumerator compares the version number that was snapshot against the current version number. https://github.com/dotnet/runtime/blob/2ba2396495c22429035d165e478672c442f81e22/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L1166-L1170 This serves as a way to flag some misuse, where mutation is performed during enumeration. The motivation here is good: help developers find misuse. There are a few problems, though: 1. It adds a little overhead. It's minimal, and this alone is not worth a change for, but it requires an extra Int32 field on the type as well as on the enumerator, it requires an increment operation as part of each mutation, and it requires an extra branch as part of each MoveNext. 2. It doesn't cover all forms of enumeration. If, for example, you enumerate a `List<T>` via `foreach (var item in list) Use(item);`, then it applies, but if you change to iterating via `for (int i = 0; i < list.Count; i++) Use(list[i]);`, then it doesn't. 3. We're considering proposals for enabling the compi
Comments (0)
No comments yet. Start the discussion.