CNA-GAP-007: CNA public headers still export Sharp Runtime's unprefixed CONTAINS and INTERNAL macros through SharpRuntimeHelper.hpp

CNA snapshot 3b43bd86  ·  Known Issues › Functional gaps  ·  source links pinned to 3b43bd86

✓

Evidence basis: source-verified at the pinned commit. Claims on this page were checked by reading the CNA source at commit 3b43bd86; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

91 headers under modules/*/include include SharpRuntime/SharpRuntimeHelper.hpp, which defines CONTAINS(STRING, SUBSTR) and an empty INTERNAL, so a game translation unit that includes such a CNA header cannot use those spellings as identifiers.

Identifier
CNA-GAP-007
Category
Functional gap
Subsystem
Core & runtime
Status
Narrowed (partially fixed; describes only what survives)
Verified against
CNA 3b43bd86 (3b43bd8687ed46523d873f9bec4b32bd8481dcb5)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
None
Affected contract
Any CNA public header that includes SharpRuntime/SharpRuntimeHelper.hpp (for example SoundEffect.hpp, AudioEngine.hpp, AudioCategory.hpp)

Expected behaviour

Including a framework header should not reserve short, common identifiers in the program's macro namespace; the XNA API a port expects occupies no macro names.

Actual behaviour at TARGET

91 public headers under modules/*/include include SharpRuntime/SharpRuntimeHelper.hpp, among them SoundEffect.hpp. That sharp-runtime header defines CONTAINS(STRING, SUBSTR) and an empty INTERNAL, so after such an include a function or enumerator called CONTAINS is rewritten and a variable called INTERNAL disappears.

Fixed since first recorded: SharpRuntime/Prop.hpp and its 31 macros (YES, NO, nothing, ref1, getter1, DEF_PROP and others) are no longer included by any public header: ec2d8b692 (CNA-DEMOS-ISSUE-008) spelled out the members ContentManager.hpp, Viewport.hpp and seven sensor reading headers generated with them. CNA closed ISSUE-008 on a complete checkpoint (6c8b042c4, 2026-10-24).

Source locations

Evidence

Checked by reading at 3b43bd86 (a grep of modules/*/include for the two includes) and the sharp-runtime header at next in the local checkout (the snapshot pins no revision); not executed. The macros belong to sharp-runtime; the limitation is CNA's because its public headers expose them.

Re-verified at c6dec91f: no public header includes SharpRuntime/Prop.hpp; 91 include SharpRuntimeHelper.hpp, whose only macros at sharp-runtime next (4e146b90) are CONTAINS and INTERNAL. CNA_DEMOS_REPAIR_MATRIX.json lists ISSUE-008 as PENDING_VERIFICATION. Not executed.

Re-verified at 3b43bd86: 91 public headers still include SharpRuntimeHelper.hpp and none includes Prop.hpp; sharp-runtime next (still 4e146b90 in the local checkout) still defines CONTAINS and INTERNAL there. CNA_DEMOS_REPAIR_MATRIX.json now lists ISSUE-008 as FIXED_VALIDATED; that closure covers the Prop.hpp macros only. Not executed.

Focused reproduction

// Illustrative; not compiled.
#include "Microsoft/Xna/Framework/Graphics/Viewport.hpp"
bool NO = false;        // preprocesses to: bool 0 = false;  -> error
int nothing = 3;        // preprocesses to: int  = 3;        -> error

Current tests

PublicHeaderMacroHygieneTests.cpp and SensorHeaderMacroHygieneTests.cpp (ec2d8b692) include the repaired headers, refuse to compile if a Prop.hpp macro is defined and use the words as identifiers. No test covers CONTAINS or INTERNAL, or includes every public header.

Regression test

Extend the hygiene tests to include every public header and declare CONTAINS and INTERNAL as identifiers; the fix is prefixing the two macros in sharp-runtime or keeping SharpRuntimeHelper.hpp out of CNA's public headers.

Blast radius

Game code that uses CONTAINS or INTERNAL as an identifier in a translation unit that includes an affected CNA header. Behaviour of CNA itself is unaffected.

Workaround

Rename the colliding identifiers, or #undef the macro after the last CNA include.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.