how to avoid "already defined error" in C++ - c++

I am gettings these type of errors in a MFC VS6 project while linking the application:
msvcrt.lib(MSVCRT.dll) : error LNK2005: _atoi already defined in LIBC.lib(atox.obj)
I know what it means (a function exists in 2 different libraries); to solve it I should have to exclude one of the 2 libraries (msvcrt.lib or libc.lib).
But if I do this there are all kinds of unresolved external errors. So I would like to keep using both libraries.
Is there any way to tell the linker that I want to use the _atoi function in libc.lib and not in msvcrt.lib (or the other way around)?
Any help or direction would be great.

This error certainly means that you're linking two pieces of codes that have been compiled using distinct runtime libraries. MSVCRT.dll is the dynamic version, while LIBC.lib is the static one. If you do this, all hell break loose. Try finding which parts of your code use which version, and sort this out.

You have a runtime clash. Using multiple runtime libraries is generally a bad thing.
You can use /nodefaultlib:msvcrt (or /nodefaultlib:libc) in your linker options to exclude one or the other.
Actually, before resorting to that, check your project settings. If I recall correctly, libc is the single-threaded runtime in VS6, and msvcrt is the multi-threaded runtime. If you have multiple projects in your solution, make sure they're all using one or the other.

There seems to be an option which you can use to ignore errors like this: in projectsettings > link > check 'Force file output'. This will generate the program even if there are linkerrors.
The Build output gives something like this:
msvcrt.lib(MSVCRT.dll) : warning LNK4006: _atoi already defined in LIBC.lib(atox.obj); second definition ignored
Of course you will need to use this option with care as it can generate an application which won't work in some cases, but here it probably doesn't do any harm (I hope).
Thank you for the other replies, but that didn't seem to be an option in my particular case.

Related

How to avoid "LNK2005 Already Defined error" in case of two static libraries that use same another static library?

Situation:
Static library LIB1, compiled from source and linked as lib1.lib (with /MD).
Uses library LIB2 and has inside objects from lib2.lib
Static library LIB2, also compiled with /MD.
EXE that (not directly) depends on both libraries.
Result of linking this EXE on MSVC 15.9.19: a lot of LNK2005 errors like
lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"
Also I get a lot of warnings like
lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info
The question: why didn't the linker merge duplicate definitions? How do I diagnose the exact reason for this problem?
Thanks!
UPDATE:
The errors are NOT about the standard library. They are about the Google Protobuf functions. LIB2 is Google's libprotobuf.lib. LIB1 is also Google's OR-Tools library that uses Protobuf. But we also use Protobuf, hence the conflict!
This link to MSDN will almost certainly help.
As you say these are not standard C/C++ functions, you can ignore the sections about the mixing Debug and Release code. Unfortunately this still leaves you with plenty of possible causes. This one is a good one to rule out.
This error can occur if you mix use of static and dynamic libraries when you use the /clr option.
If you view the command line options as you compile, either by switching on verbose mode or examining the properties of each file.
Once this is ruled out, all the other causes are that you literally declaring the same thing (function/variable) twice. The most likely way for this to happen is to put something (like a function) in a header file, which is included by more than one module file. Diagnosing this without seeing the code is hard. You must pick one of the errors, and select part of the name that is not mangled, basically the human readable bit. You then need to examine where it is declared, and see if is in a header. If it is not, you must be including a non-header from a source file. A quick (and dirty) way to find where a file is included from is to add a #pragma message to the file, then recompile one file at a time to see when it is printed. To understand why it is included use show includes.
If the symbol is declared from a header file, you must fix it, by making it a forward declare.
If you don't know how to do this, I would suggest starting a new question, along the lines of, "how do I forward declare this?". It should get you answers pretty quickly.
Hope this helps.

How to find origin of a apparently buggy LNK2005 (symbol already defined)?

I'm trying to compile a src code of an application that have the libs stripped from the files.
I already downloaded, compiled and linked each lib the project needs but I'm having trouble with a specific one: crypto (https://www.cryptopp.com/).
I receive a LNK2005 (symbol already defined) when trying to compile. The exact error message is:
Error LNK2005 "public: __cdecl CryptoPP::Rijndael::Enc::Enc(void)"
(??0Enc#Rijndael#CryptoPP##QEAA#XZ) already defined in
cryptlib_5_65-v141-x64.lib(rijndael.obj) IGC.GameServer D:\MU
Online\IGCN_S9E2_Emu\source\GameServer\PacketEncrypt.obj 1
Error LNK1169 one or more multiply defined symbols
found IGC.GameServer D:\MU
Online\IGCN_S9E2_Emu\source\Output\IGC.GameServer\Release\IGC.GameServer.exe 1
Apparently the linker is complaining that the type public: __cdecl CryptoPP::Rijndael::Enc::Enc(void) is being defined twice (in rijndael.obj - crypto lib - and in PacketEncrypt.obj - the project I'm trying to compile).
I already had fixed the LNK2005 a lot of times in the past but this time I just can't figure out what's hapening.
As I don't know what can be causing this error I don't know exactly what to share here regarding the code. Bellow is some code I think that can help but if you feel something is missing you can ask for more code.
Declaration of the type being defined twice
Problematic declaration
If I comment the two lines selected in the second print (and obviously cut off their references in the code) I can compile the project without any problem.
Thanks in advance.
So you are linking cryptlib_5_65 to IGC.GameServer, but the cryptlib already have that function. I am guessing that rijndael.cpp actually belongs to cryptlib project, but you added the source file to GameServer project as well. Check if that file is not in both projects and if so, remove it from the GameServer.
Implementation should be only in one of them.
It might not be the case, but the lack of better info from you, makes it difficult to find solution.
I would post it as a comment, but not enough points on my side.

Can not find bsearch(vc2008) even include the header file

I maintain an old project and encountered some linker errors.
The error message is:
error LNK2019: unresolved external symbol __imp__bsearch referenced in function "bool __cdecl is_sync_host
As far as I know, the bsearch function is included in the header file "cstdlib" or "stdlib.h", but even if I include the header, I can't find "bsearch".
I suspect this is due to the fact that this old project ignores some lib because of symbol conflicts (I also don't know why they prefer to omit the lib instead of renaming the functions)
The ignored libs : msvcrt.lib;msvcrtd.lib;libcmt.lib;libc.lib
I try to add those ignored libs back, but then I encounter a lot of "symbol redefinition" problems and I don't think that renaming those functions is an applicable solution.
I found a work around (replace the bsearch to std::binary_search), but I want to know why and how to solve this problem properly (how comes the compiler can't find the bsearch?). Thanks.
error LNK2019:
This is a linker error. Your code compiled just fine (.c > .o), it is the linking that gives you problems (.o > .exe).
The ignored libs : "msvcrt.lib;msvcrtd.lib;libcmt.lib;libc.lib"
This means the code is ignoring the C standard library, so no wonder it doesn't find the standard bsearch() function...
The question is, why? There is simply no reason (that I could think of) for well-written code to explicitly ignore the standard library.
I try to add those ignored libs back, but then I meet a lot of "symbol redefinition" problems...
Which brings me to the conclusion that your code is not "well-written", at which point it is very difficult to give advice without seeing the code, or telling you to "ditch it, it's crap". ;-)
I don't think that rename those functions is an applicable solution.
If you have functions in your project that are named like standard library functions, unless your project is a standard library, they are misnamed and should be renamed.
But at this point, I would really like to see the code in question to figure out what the original programmer might have had in mind...

Mysterious "unresolved symbols" linker errors when compiling against large static lib

I am receiving a lot of strange LNK2001 and LNK2019 errors when attempting to compile and link against a somewhat large static library (developed in-house). Here are the facts:
There are several static libs (most built in-house) all compiled into one large wrapper static lib for public consumption ("Pimpl" idiom). Essentially, we have libs A, B, and C all compiled into an internal/private lib called D. Then, we have an external/public lib that wraps around D called E.
The final product is not an executable, but a plug-in for Adobe Illustrator. Plug-ins are essentially just a DLL with a couple special resources and a special entry point (PluginMain() function). Compiling and linking works just great until I use the /INCLUDE option to specify that PluginMain should always be exported.
Creating a plug-in and linking against lib D works fine (no errors whatsoever). Creating a plug-in and linking against lib E gives over 100 unresolved symbol errors (symbols that should be present in E).
When I run DUMPBIN on the E.lib file, it appears to have all the symbols that the linker is complaining about when trying to create a plug-in. However, I'm not entirely certain I understand all the output syntax from DUMPBIN...
The libs are all cross-platform and compile and link just fine with GCC/LLVM on Mac.
Most of the functions that the linker complains about are either plain functions or static member functions. Most of those look suspiciously like functions that the compiler might try to inline. I have tried disabling optimization and/or automatic inlining, but the same link errors are still present.
Can anyone point me in the direction of some compile and/or link settings that might resolve the issue? Settings that are commonly misconfigured in situations like this?
Perhaps there is a setting I missed that is causing the linker not to export these symbols when linking E? Perhaps there is a setting that forces the linker to export ALL symbols when linking E that I can try? Maybe a utility exists to help me inspect the lib symbols myself for a clue?
I feel like I've tried everything, but it never hurts to ask. Thanks all.
EDIT 1: snowdude requested an actual link error:
E.lib(PathArt.cpp.obj) : error LNK2001: unresolved external symbol "private: __thiscall E::PathSegPoint::PathSegPoint(struct D::PathSegPoint const &)" (??0PathSegPoint#E##AAE#ABU0D###Z)
I should add that E::PathSegPoint::PathSegPoint(const D::PathSegPoint&) is a private constructor for constructing an external/public consumable E::PathSegPoint object from an internal/private D::PathSegPoint object. Again, this is the "Pimpl" idiom. Some classes/functions are friends of E::PathSegPoint to enable this sort of construction.
I thought I'd post an answer in case anyone shows up to this page in the future.
For several reasons a few years ago, we started compiling these libraries with the Intel C++ compiler inside Visual Studio. Some of these reasons have changed, and we needed to switch back to the MSVC compiler. Upon switching to the MSVC compiler, these linker errors disappeared!
I don't know why or how the Intel C++ compiler developed these link problems, but it's entirely possible that this is a bug.

Link issues (VC6)

I've opened an old workspace that is a libray and its test harness. It used to work fine but now doesn't and older versions of the code don't work either with the same errors. I've tried recreating the project and that causes the same errors too. Nothing seems out of order in project settings and the code generated works in the main app.
I've stripped out most of the files and got it down to the bare minimum to generate the error. Unfortunately I can't post the project as this is used in production code.
The LNK2001 linker error I get usually means I've left off a library or forgot to implement a virtual function. However this is part of the standard template library - and is a header at that.
The code that is listed as having the problem in IOCompletionPort.obj doesn't actually use std::string directly, but does call a class that does: Comms::Exception accepts a std::string and the value of GetLastError or WSAGetLastError.
The function mentioned in the error (GetMessage) is implemented, but is a virtual function so other classes can override it if need be. However it appears that the compiler has made it as an Ansi version, but I can't find any options in the settings that would control that. I suspect that might be the problem but since there's very little in the way of options for the library I have no way of knowing for sure. However both projects to specify _MBCS in the compiler options.
--------------------Configuration: TestComms - Win32 Debug-------------------- Linking... Comms.lib(IOCompletionPort.obj)
: error LNK2001: unresolved external symbol "public: virtual class
std::basic_string,class
std::allocator > __thiscall
Comms::Exception::GetMessageA(void)const " (?GetMessageA#
Exception#Comms##UBE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
Debug/TestComms.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
TestComms.exe - 2 error(s), 0 warning(s)
Any suggestions? I've lost most of the morning to this and don't want to lose most of the afternoon too.
One possibility lies with Win32 ANSI/Unicode "name-mangling", which turns the symbol GetMessage into either GetMessageA or GetMessageW. There are three possibilities:
Windows.h hasn't been loaded, so GetMessage stays GetMessage
Windows.h was loaded with symbols set for ANSI, so GetMessage becomes GetMessageA
Windows.h was loaded with symbols set for Unicode, so GetMessage becomes GetMessageW
If you've compiled two different files in ways that trigger two different scenarios, you'll get a linker error. The error message indicates that the Comms::Exception class was an instance of #2, above -- perhaps it's used somewhere that windows.h hasn't been loaded?
Other things I'd do in your place, just as a matter of routine:
1) Ensure that my include and library paths don't contain anything that I'm not expecting.
2) Do a "build clean" and then manually verify it, deleting any extra object files if necessary.
3) Make sure there aren't any hardcoded paths in include statements that don't mean what they meant when the project was originally rebuilt.
EDIT: Fighting with the formatting :(
#Curt: I think you came the closest. I haven't tested this but I think I sort of gave the answer in my original question.
GetMessage is a define in Windows.h wrapped in a ifndef block to switch between Ansi (GetMessageA) and Unicode (GetMessageW).
Presuming you haven't futzed around with the Project settings deleting something you ought not have (which is where I'd expect external dependencies like User32.lib to be):
Check Tools | Options | Directories | Libraries (going from memory here) and ensure that you're not missing the common-all-garden variety lib directories (again, without VC6 in front of me, I can't tell you what they are)
This is a general problem with the way Microsoft handled the ANSI vs. Unicode APIs. Since they are all (or pretty much all) done by defining macros for the function names that resolve to the 'A' or 'W' versions of the function names you cannot safely have an identifier in your namespace/class/struct/enum/function that matches a Windows API name.
The windows.h macros run roughshod over all other namespaces.
windows.h is declared at the top of IOCompletionPort.h as an include - I was sick of seeing 7 lines just to include 1 file so I have wrapped it its own file and includes that itself. This also contains some additional #defines (i.e. ULONG_PTR) as our main app won't compile with the Platform SDK installed:-(
That is confirmed. Nothing is out of place.
I've done that - deleted the build directories
I never use hard-coded paths.