Skip to content

Fix missing return statements in SetFunction placeholders (breaks MSVC/Windows builds) - #58

Open
Fkroune wants to merge 1 commit into
decile-team:masterfrom
Fkroune:fix/msvc-missing-return-in-setfunction-placeholders
Open

Fkroune wants to merge 1 commit into
decile-team:masterfrom
Fkroune:fix/msvc-missing-return-in-setfunction-placeholders

Conversation

@Fkroune

@Fkroune Fkroune commented Sep 19, 2026

Copy link
Copy Markdown

What

SetFunction::evaluate, evaluateWithMemoization, marginalGain, marginalGainWithMemoization, and getEffectiveGroundSet (cpp/SetFunction.cpp) are pure virtual methods (see cpp/SetFunction.h) that also carry empty out-of-line base-class definitions here — every concrete subclass (FacilityLocation, GraphCut, etc.) overrides them with a real implementation, so these particular bodies are never actually executed. But each has a non-void return type with no return statement at all, which is undefined behavior per the C++ standard regardless of reachability.

GCC/Clang only warn about this (-Wreturn-type). MSVC's optimizer, specifically with whole-program optimization (/LTCG, the default for a Release setup.py extension build), treats it as a hard link-time code generation failure:

SetFunction.cpp(18) : error C4716: 'SetFunction::getEffectiveGroundSet': must return a value
LINK : fatal error LNK1257: code generation failed

This means pip install submodlib currently cannot build from source on Windows at all (confirmed on a clean windows-latest GitHub Actions runner, MSVC from Visual Studio 2026/toolset 14.51).

Fix

Each placeholder now returns a default value of its own declared type (0.0 for the double-returning methods, an empty unordered_set for getEffectiveGroundSet) — semantically inert, since these bodies are never actually called by any real code path, and removes the undefined behavior either way.

Minimal, mechanical, 5-line diff — no behavior change for any real usage.

Verification

Found via, and being verified against, a downstream project's real Windows CI build (adding it to this PR once that run completes).

evaluate(), evaluateWithMemoization(), marginalGain(),
marginalGainWithMemoization(), and getEffectiveGroundSet() are pure
virtual methods (SetFunction.h) that also carry empty out-of-line
definitions here in the base class. Every concrete subclass overrides
them with a real implementation, so these bodies are unreachable in
practice -- but their non-void return types with no return statement
at all is undefined behavior per the C++ standard regardless of
reachability, and MSVC's optimizer (whole-program /LTCG) treats it as
a hard link-time code generation failure (LNK1257) rather than the
warning GCC/Clang emit, blocking any Windows build of this package
from source.

Fix: each placeholder now returns a default value of its own declared
type (0.0 for the double-returning methods, an empty unordered_set for
getEffectiveGroundSet) -- semantically inert since these bodies are
never actually executed by real call sites, and removes the undefined
behavior regardless.

Found and being verified via a downstream project's (rushcut,
github.com/Fkroune/RushCut) real Windows CI build, which hit this
exact LNK1257 failure building submodlib from source.

This branch has not been deployed

No deployments
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