0

I have 3 files in a Visual Studio project: test.cpp, date.cpp and main.cpp -

test.cpp:

int g() { return 0; }

date.cpp:

/*totally empty*/

main.cpp:

#include "test.cpp"
#include "date.cpp"

int main() { return g(); }

I understand that defining functions in a header file leads to violation of One-Definition Rule if header file is called multiple times. But here, I am calling it only once from only one file/translation unit. Why is it still throwing LNK2005?

Anurag Kalia
  • 4,668
  • 4
  • 21
  • 28

3 Answers3

4

You should not include test.cpp and date.cpp. Instead, you should write test.h and date.h, and include it:

test.h

int g();

date.h

// Contains prototypes for functions inside date.cpp

main.cpp

#include "test.h"
#include "date.h"

int main() { return g(); }
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

You are including "test.cpp" in "main.cpp" - this is most likely wrong, as Visual Studio will ALSO compile "test.cpp" as a separate file, and then link "test.obj" with "main.obj" (those are the files generated by the compiler) into "main.exe". When it then finds "g()" in both "test.obj" and "main.obj", it says "Huh? Why have you got two of these" (or, in linker terms "multiple defined symbols").

The solution is to have a "test.h" that declared void g(); and then use that to include into "main.cpp".

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • I wish I could combine the three answers into one. But this one is closest to what I actually intended to ask. So there goes my vote. – Anurag Kalia Apr 27 '13 at 20:13
2

Since test.cpp is in the VS Project, it will be compiled and lined in along with main.cpp causing the multiple definitions - unless you take special measure to prevent that from happening, like removing test.cpp from the project or setting it to be "Excluded from Build".

If you rename temp.cpp to test.h you get two benefits:

  1. VS will not automatically compile a .h when it's in a project, since it assumes that the file is intended to be included from other files instead of being stand-alone compiled.
  2. it will be less confusing to programmers about the intended use of the files
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Isn't that a mistake above? Shouldn't it be test.cpp instead of test.h? Asking to be sure. – Anurag Kalia Apr 27 '13 at 20:08
  • And thanks for the additional information. I thought compiler is neutral about extensions. Wasn't I wrong! – Anurag Kalia Apr 27 '13 at 20:14
  • I fix the typo. And while you can force the tools (VS and the compiler) to deal with the files however you name them, they do make some default assumptions based on the extension. You will also needlessly cause at least some confusion with people who have to deal with the project if you use extensions in a way that's different than expected. – Michael Burr Apr 27 '13 at 23:57