Visual Studio 2010's strange "warning LNK4042"

Viewed 45192

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 ?

11 Answers

I'd like to point out one possible reason for why the ItemType of a .h file would change from C/C++ header to C/C++ compiler:

  1. In the Solution Explorer window of VS (2019 here), right click the project name, choose Add -> New Item;
  2. Select the C++ File (.cpp) template, but type something.h in the name input area, then click OK to add it;
  3. Then you'll encounter the LNK4042 warning if the something.h file be included within more than one .cpp files.

I just overcame a similar error message, and lots more with the procedure below. Symptom: one linker error for every invocation of every function defined in a particular header, plus one at the end of output for every function defined in the header.

Then I remembered that when I had originally created this header, I accidentally had selected "add->new item->c++ file" and though I named it 'whatever.h', it seems Visual Studio considered them both the same kinds of files because of the incorrect action I used to add one. Examining the build output logs made this obvious.

SOLUTION (Using VS Community 2019)

  1. Back up project first (just to be safe).
  2. Right-click the offending header file and select "Exclude from project" (this will not delete them; the VS project will just ignore them).
  3. Do same for the matching .c or .cpp file.
  4. Do Build->Clean on project
  5. Do Build->Rebuild on project -- there of course will be errors---
  6. Right-click Header Files->Add->Existing Item, then select the .h file
  7. Right-click Source Files->Add->Existing Item, the select the .c or .cpp file
  8. Do Build->Rebuild on project.

This completely cleaned it up for me, relieving me of many irritating linker errors including LNK4042 from the title of this question.

I resolved it changing filenames in my project. There was two files named main.c and main.cpp. I changed one of them and worked.

Related