Skip to content

Fix MSVC build breaks on origin/main (stdarg.h va_list, mnmaps.c #-in-macro-arg)#131

Merged
JRickey merged 1 commit intomainfrom
agent/msvc-build-fixes
May 4, 2026
Merged

Fix MSVC build breaks on origin/main (stdarg.h va_list, mnmaps.c #-in-macro-arg)#131
JRickey merged 1 commit intomainfrom
agent/msvc-build-fixes

Conversation

@JRickey
Copy link
Copy Markdown
Owner

@JRickey JRickey commented May 4, 2026

Summary

Two pre-existing MSVC build breaks have been blocking Windows RelWithDebInfo builds since the src/decomp/ submodule migration (#129) landed. Reproduce on a clean checkout of origin/main with no other patches applied.

What was broken

(1) decomp/include/stdarg.hva_list __builtin_va_list redefinition on MSVC

The #ifndef __sgi block re-#defines va_list __builtin_va_list. MSVC has no __builtin_va_list intrinsic, so this fires C2061 (syntax error: identifier '__gnuc_va_list') cascading from the __GNUC_VA_LIST typedef.

MSVC fully sets up va_* via <vadefs.h> + __crt_va_* in the existing #ifdef _MSC_VER block at the top of the file, so it just needs to skip the GCC-builtin branch AND the IDO #else branch (the IDO branch would re-typedef char* va_list after vadefs.h already typedef'd it).

Fix: wrap both the GCC-builtin and IDO branches in #ifndef _MSC_VER.

(2) decomp/src/mn/mnmaps/mnmaps.c:1073#ifdef PORT inside macro arg list

#ifdef PORT directives sit inside the lbRelocGetFileData(...) argument list. lbRelocGetFileData is a function-like macro defined in src/lb/library.h:

#define lbRelocGetFileData(type, file, offset) \
    ((type) ((uintptr_t)(file) + (intptr_t)(offset)))

The C standard says # directives inside function-like macro args are undefined behavior. Clang/gcc accept leniently, MSVC rejects with C2059 (syntax error: '#') regardless of /Zc:preprocessor (the conforming preprocessor turns it into a C5101 warning AND a C2059 error).

Fix: hoist the PORT/non-PORT conditional values into local variables before the macro call so the macro args themselves are directive-free. Same end semantics, no behavior change — it's purely a textual/structural fix to satisfy the C-standard rule on macro-arg preprocessor directives.

Scope

A tree-wide scan for #ifdef PORT at non-zero paren depth turned up 30 candidate sites in 11 files, but 29 of them sit inside regular function calls (which MSVC's preprocessor accepts because the rule only applies to function-like macro args, not function args). Only the two #ifdef PORTs in mnmaps.c needed restructuring. No other files affected.

Test plan

  • Clean origin/main + this branch on Windows (MSVC 19.44.35225): build error before — error C2061: syntax error: identifier '__gnuc_va_list' and error C2059: syntax error: '#'. Build succeeds after, produces BattleShip.exe.
  • Bytes-equivalent change: mnmaps.c fix is purely a hoist of compile-time-conditional values out of a macro arg list. Local-variable values are identical to the inline expressions they replace, both for PORT and non-PORT branches. No runtime behavior change.
  • Linux/macOS unaffected: clang/gcc were already accepting both constructs; the #ifndef _MSC_VER guard makes the GCC-builtin branch fire identically as before, and the mnmaps.c hoist is just a refactor. Cross-platform CI would confirm.
  • Game smoke: launch the produced BattleShip.exe, verify VS match boots and a Training-mode wallpaper renders (the only path the mnmaps.c hoist touches).

Submodule pointer bump

Decomp pushed to JRickey/ssb-decomp-re#agent/msvc-build-fixes at commit 62ba3fd23. Outer commit 69b912b bumps the submodule pointer.

🤖 Generated with Claude Code

Bump decomp submodule to JRickey/ssb-decomp-re#agent/msvc-build-fixes
(commit 62ba3fd23) which contains two pre-existing MSVC build breaks
that have been blocking Windows RelWithDebInfo builds since the
src/ → decomp/ submodule migration (#129) landed:

(1) decomp/include/stdarg.h re-`#define`s `va_list __builtin_va_list`
    on MSVC, where that intrinsic doesn't exist (C2061). Fixed by
    guarding the GCC-builtin branch with `#ifndef _MSC_VER`; MSVC
    falls through the existing `#ifdef _MSC_VER` block at top via
    <vadefs.h> + __crt_va_*.

(2) decomp/src/mn/mnmaps/mnmaps.c (line 1073) puts `#ifdef PORT`
    directives inside the `lbRelocGetFileData(...)` macro argument
    list. C standard says `#` in function-like macro args is
    undefined behavior; clang/gcc accept leniently, MSVC rejects
    with C2059. Fixed by hoisting the conditional values out into
    local variables before the macro call. A tree-wide scan turned
    up 30 candidate sites in 11 files but 29 of them sit inside
    regular function calls (accepted), so this was the only one
    that needed restructuring.

Verified: clean RelWithDebInfo Windows build (MSVC 19.44.35225)
succeeds end-to-end and produces BattleShip.exe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JRickey JRickey merged commit f4a4c63 into main May 4, 2026
@JRickey JRickey deleted the agent/msvc-build-fixes branch May 4, 2026 00:57
JRickey added a commit that referenced this pull request May 4, 2026
NamedTemporaryFile on Windows holds an exclusive file lock until the
context exits, which would block clang from writing to the path even
after `with` exits cleanly (Windows file-mapping semantics differ from
POSIX). mkstemp returns a file descriptor we close immediately,
giving clang an unlocked path on every platform.

The C++ port code uses std::getenv with the same C++17 init-statement
if pattern as five existing port/*.cpp files (port.cpp:739,
port_save.cpp, renderdoc_trigger.cpp, lbreloc_byteswap.cpp, etc.)
that are known to compile cleanly under MSVC, so port/port.cpp's
SSB64_RELOC_FROMSOURCE block is MSVC-compatible without further
changes.

The MSVC fixes in PR #131 (decomp submodule bump 7a0da1e → 62ba3fd
for the stdarg.h va_list guard + mnmaps.c #-in-macro-arg restructure)
are pre-existing breaks unrelated to this branch — but the rebase
onto post-#131 main means we're now on the MSVC-clean submodule
state.
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