Skip to content

1:length(x) pattern causes silent mis-iteration when length(x) == 0 #80

Description

@bradduthie

Files: Widespread — every for(i in 1:length(x)) pattern in the codebase.

Affected locations:

File Lines
R/gmse_summary.R 21, 44, 84, 167
R/gmse_apply.R 121, 1674, 1699, 1736, 1900, 1938, 1954, 2013, 2019, 2475, 2565, 2697, 2933
R/plotting.R 148, 364, 580, 609

Description: This is a well-documented R gotcha. The expression 1:length(x) looks innocuous but silently misbehaves when x has length zero:

x <- numeric(0)      # empty vector, length = 0
1:length(x)          # 1:0 → c(1, 0)  ← NOT what you expect

Instead of producing an empty integer vector, 1:0 produces c(1, 0). The loop body then executes twice — once for i = 1 and once for i = 0 — rather than skipping entirely. This can silently write to invalid indices or operate on non-existent elements without raising an error.

Why it matters: If a GMSE simulation ever produces an empty resource type vector, an empty agent array, or an empty observation record, any loop using this pattern will run twice with incorrect indices rather than being skipped. The code will not crash, but it may silently corrupt array entries at index 0 (which in R assigns to a new element or overwrites internal structure in certain contexts). In practice, bugs introduced this way would manifest as hard-to-debug numerical errors in simulation outputs rather than explicit crashes, making them very difficult to track down.

How to fix: Use seq_along(x) or seq_len(length(x)) instead:

# Instead of:
for(i in 1:length(x)){ ... }

# Use:
for(i in seq_along(x)){ ... }

seq_along(x) safely returns an empty integer vector when x has length 0, so the loop body never executes. This is the idiomatic R pattern and should be used consistently throughout the codebase.

Metadata

Metadata

Assignees

Labels

To doThings to do to improve GMSEbugBugs to address in GMSE code

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions