Skip to content

Add CI guard against C++ alternative operator tokens - #128

Merged
shimwell merged 1 commit into
making-wheel-3from
format-check-alternative-tokens
Aug 5, 2026
Merged

Add CI guard against C++ alternative operator tokens#128
shimwell merged 1 commit into
making-wheel-3from
format-check-alternative-tokens

Conversation

@shimwell

@shimwell shimwell commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Why

MSVC accepts the C++ alternative operator tokens (and, or, not and friends) only when /permissive- is passed, which is not the default for a CMake-driven build. One of these in a widely included header breaks the entire Windows build.

The cost is badly out of proportion to the cause. Two occurrences of and in mesh.h, fixed in openmc-dev#4048, produced over a hundred cascade errors in a Windows build probe, spread across unrelated translation units: missing members of openmc::simulation, undefined UnstructuredMesh members, and complaints about MSVC's own internal _Cosh and _Exp names. None of it pointed at the real line, which was the very first error in the log and easy to miss among the noise.

clang-format does not rewrite these tokens, so nothing in CI catches them today.

What

  • tools/ci/check_alternative_tokens.py, which scans src/ and include/ and exits non-zero on any alternative operator token.
  • A fast alternative-tokens job in the existing C++ Format Check workflow.

The check strips comments and string literals before scanning, so it does not trip on prose. Newlines are preserved during stripping so reported line numbers match the original file. Vendored code under src/external/ is skipped.

It reports file, line and the offending source line:

include/openmc/mesh.h:636: alternative token 'and' -> use the symbolic operator
    if ((idx > 0) and (idx <= N)) {

The script takes optional path arguments so it can be run locally during development:

python tools/ci/check_alternative_tokens.py

Testing

  • Passes on current develop with no findings, so it does not introduce a red CI.
  • Run against mesh.h as of 163fdf78^ it flags exactly the two real sites at lines 636 and 701, matching the locations MSVC reported.
  • Checked against a case containing the tokens inside line comments, block comments, string literals, an escaped quote, #include <complex>, and the identifiers n_and, order, nothing and sword: no false positives, while genuine and, not and bitor operators on adjacent lines are all caught.

MSVC accepts the alternative operator tokens (and, or, not and friends)
only when /permissive- is passed, which is not the default for a
CMake-driven build. A single one of these in a widely included header
therefore breaks the entire Windows build.

Because the failure is a parse error, the cost is out of proportion to
the cause. Two occurrences of 'and' in mesh.h (fixed in openmc-dev#4048) produced
over a hundred cascade errors spread across unrelated translation units,
including complaints about members of openmc::simulation and about
MSVC's own internal _Cosh and _Exp names, none of which pointed at the
actual line.

clang-format does not rewrite these tokens, so nothing in CI catches
them today. This adds a check that strips comments and string literals
before scanning, so it does not trip on prose or on identifiers such as
n_and and order. It reports file, line and the offending source line,
and skips vendored code under src/external/.

The script takes optional path arguments so it can be run directly
during development:

    python tools/ci/check_alternative_tokens.py
@shimwell
shimwell changed the base branch from develop to making-wheel-3 August 5, 2026 16:12
@shimwell
shimwell merged commit ead172c into making-wheel-3 Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant