6

I have a function bar() that I don't actually call, that calls unimplemented foo():

void foo();
void bar()
{
    foo();
}
int main()
{

}

If I package each function in a separate section/COMDAT and ask the linker to remove unused sections/COMDAT, I can get gcc to compile the program

gcc -ffunction-sections -Xlinker --gc-sections LinkerFunctions.cpp

but the equivalent in Visual C++ 2019

cl /Gy LinkerFunctions.cpp /link /OPT:REF

barks that

error LNK2019: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ) referenced in function "void __cdecl bar(void)" (?bar@@YAXXZ)

How can I get msvc to compile the program?

Bruno Martinez
  • 2,850
  • 2
  • 39
  • 47

2 Answers2

5

Got your example working by adding inline, even after adding __declspec(noinline) to prevent actual inlining.

void foo();

__declspec(noinline)
inline void bar()
{
    foo();
}

int main()
{

}

Tried because the documentation says:

Inlined functions and member functions defined inside a class declaration are always COMDATs.

Not sure however if it is robust solution, or works just in this particular case.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • `static void bar() { ... }` appears to work, too. It looks like otherwise VS has a problem realizing that `bar` is not referenced from elsewhere, even with "*whole program optimizations*" turned on. – dxiv Apr 27 '20 at 00:48
2

Accidentally found a linker switch for that:

cl incomplete.cpp /link /FORCE:UNRESOLVED

Will give a warning but in fact will work.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79