docs: brace position on an inline structor is load-bearing for header-offsets - #2068
Merged
Conversation
…-offsets
Inlining a destructor to make it scoreable moves a function body into a
struct that check_header_offsets.py parses. That gate arms its body-skip
only from a brace on the signature line, so an Allman brace falls through
to declaration parsing and is reported UNPARSED -- and one unparsed line
suppresses the field walk for the whole header.
Measured by rewriting only the destructor of include/dScMgBase_c.h:
one line, with body 40 commented fields, 0 unparsed, spans 0x4660
one line, empty {} 40 commented fields, 0 unparsed, spans 0x4660
Allman, with body 0 commented fields, 2 unparsed, spans 0x50
Allman, empty 0 commented fields, 1 unparsed, spans 0x50
Two conditions narrow it and both hold for inline-destructor promotions:
a derived class whose structor is declared before any field. ArrowLift.h,
whose destructor follows its fields, measures identically in both styles.
An empty Allman body breaks it where an empty one-line body does not.
Also records that a marker on a still-unnamed member cannot lift that
member's own score, since score_member recomputes real_name from the
symbol -- the marker is there to protect its neighbour.
Docs only. No header, source or config file is touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdCK1xgrJdiJzPCh3bAJfQ
✅ PR validation — Passednoverify: no source/build-data changes in this PR Each changed |
This was referenced Aug 31, 2026
PoleLift: define the destructor in the class body (and why promotion stops at the coined name)
#2066
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #2065, same file. Two things the
@symbolsection left out, both of which the inline-destructor wave will hit immediately.1. Brace position on an inline structor is load-bearing
Inlining a destructor to make it scoreable moves a function body into a struct that
tools/check_header_offsets.pyparses. That gate arms its body-skip only when the brace is on the signature line:Written Allman,
skip_bodynever arms and the body's lines fall through to declaration parsing.I measured it rather than reasoning about it, rewriting nothing but the destructor of
include/dScMgBase_c.h— a derived class that declares its destructor first, which is the shape every inline-destructor promotion produces:The UNPARSED line exits 1, so it is loud — but green on
origin/main, which makes it a merge-tree-only red:premerge_check.pyshows it, the branch's own CI does not. The quiet half is worse. One unparsed line suppresses the field walk for the entire header, so0 commented fieldsis not a clean pass, it is no check at all: forty fields stopped being checked and the span fell back to the base's0x50. That is this tool's own documented silent-no-op shape, arriving a fourth way.Two conditions narrow it, and both hold for exactly the promotions this document covers — a derived class (a non-derived one is called unmodelled at its first method line and never reaches the brace) whose structor is declared before any field, the
dScene_c.hkey-function convention.include/ArrowLift.h, whose destructor follows its fields, measures identically in both styles; the method line ends the field list and the stray brace is never read. And an empty Allman body breaks it where an empty one-line body does not — it is the newline that costs, not the statements.2. A marker on a still-unnamed member buys nothing for that member
score_memberrecomputesreal_namefrom the symbol rather than the fragment, so a member still calledfunc_ov006_0210a534fails that criterion whichever text it is scored against. Marking it is still right, because the boundary protects its neighbour — but do not expect the marker to move its own score. Renaming does that.Scope and limits
Docs only: one file,
notes/tu-promotion-conventions.md. No header, source or config file is touched, so no ROM byte can move.This is a defect in the gate, not in the style, and I have filed it as one — arming
skip_bodyfrom a following-line brace is a small change but it risks newly-reding headers and wants measurement across all 508 before it lands. Until then brace position is load-bearing and belongs in the conventions doc.The Allman hazard was first noticed by another session on a different header; I did not take it on trust — everything above is my own reproduction, on a header that is on
main, and it corrects the original report in two ways (the empty-body case also breaks, and the declared-before-fields precondition is required).