Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unresolved external symbol referenced in function removed by /OPT:REF

Tags:

visual-c++

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?

like image 599
Bruno Martinez Avatar asked Apr 15 '20 19:04

Bruno Martinez


People also ask

How do I fix unresolved external symbol?

So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.

What causes unresolved external symbol?

The compiler can identify when a symbol isn't declared, but it can't tell when the symbol isn't defined. It's because the definition may be in a different source file or library. If a symbol is referred to but never defined, the linker generates an unresolved external symbol error.

What kind of error is unresolved external symbol?

So, as a result - an "undefined reference/unresolved external symbol error" happens when the linker cannot find global symbols in the object files.

How do I fix unresolved external symbol lnk2001?

To fix this issue, add the /NOENTRY option to the link command. This error can occur if you use incorrect /SUBSYSTEM or /ENTRY settings in your project. For example, if you write a console application and specify /SUBSYSTEM:WINDOWS, an unresolved external error is generated for WinMain .


1 Answers

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.

like image 166
Alex Guteniev Avatar answered Sep 20 '22 13:09

Alex Guteniev