[C++] Visual Studio 2010's strange “warning LNK4042”



Answers

I had a similar problem with linker warning LNK4042: object specified more than once; extras ignored. In my case Visual Studio was trying to compile both header and source files with the same name - MyClass.h and MyClass.cpp. It happened because I renamed .cpp file to .h and Visual Studio got confused. I noticed the problem by looking at the compiler logs in the Debug directory. To resolve just remove .h file from the project then add it again.

Question

I've just been beaten (rather hardly) on the head by some non-trivial warning from Visual Studio 2010 (C++).

The compilation gave the following output:

1 Debug\is.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\make.obj : warning LNK4042: object specified more than once; extras ignored
1 Debug\view.obj : warning LNK4042: object specified more than once; extras ignored
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl test::identity::view(void) (?view@identity@test@@YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity@0test@@YAXXZ)
1 identity.obj : error LNK2019: unresolved external symbol void __cdecl test::identity::make(void) (?make@identity@test@@YAXXZ) referenced in function void __cdecl test::identity::identity(void) (?identity@0test@@YAXXZ)
1 range.obj : error LNK2019: unresolved external symbol void __cdecl test::range::is(void) (?is@range@test@@YAXXZ) referenced in function void __cdecl test::range::range(void) (?range@0test@@YAXXZ)

Linker errors are always a pain to debug... but there were unresolved references, and so I checked... but the source is well-formed... and finally it hit me:

My folder hierarchy looks like so:

src/
  identity/
    is.cpp
    make.cpp
    view.cpp
  range/
    is.cpp
    make.cpp
    view.cpp

and so does the hierarchy in the Solution (I always set it up so that it mimicks the "real" folder structure).

And the diagnostic outputs:

Debug\is.obj
Debug\make.obj
Debug\view.obj

Along with a warning which says that the .obj has been passed twice to the linker and that one will be ignored.

Search no more: Visual has neatly flatten my folder hierarchy, and therefore is unable to neatly compile the source.

At the moment, I am simply thinking of renaming the files, that should cover the issue...

... but is there a way to have Visual Studio NOT flatten the file hierarchy ?




Alternatively to deleting and making a new file you can change the compile/include settings.

Go to your project.vcxproj file, open it with an editor, find the html like line <ItemGroup>.

It should look something like:

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

and

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

Assuming your implementation files are .cpp and your declarations are .hpp. Make sure your all your implementation files are listed between the first section if you have more then one and likewise for the second section for multiple declaration files.




I used to have in the same project .c and .cpp files with the same filenames. The files were in folders all over the place and the solutions provided by others created a mess, and folder hell (in my case). Even Release builds would overwrite Debug builds!

A good (not perfect) solution would be to use $(ParentName), but for some reason beyond anyone's grasp it has been removed from later versions of Visual Studio (2015+).

What I use succesfully now is: $(IntDir)%(Filename)%(Extension).obj

which at least separates .c built object files from .cpp.




Right click on header file -> Property -> ItemType (select C/C++ Header). Do the same with Cpp file but select C/C++ COmpiler (it's work for me)




Links