0

I'm facing a strange problem in a program I'm writing. The error is the following one:

Error 9 error LNK2005: "struct statistics __cdecl findStatistics(class std::vector,class std::allocator > >)" (?findStatistics@@YA?AUstatistics@@V?$vector@V?$Point_@H@cv@@V?$allocator@V?$Point_@H@cv@@@std@@@std@@@Z) already defined in imageProcessing.obj C:\Users\BPeixoto\Documents\Visual Studio 2012\150603_testeDirection_v4\testeDirection\main.obj

I'm working with object tracking and the function "findStatistics" work to calculate the standard deviation and the mean of the points which are supposed to be the centroid of the robot. The function findOutliers, afterwards, calculate how many points are outside the region created in hand of the standard deviation and mean values.

If necessary, I can post the necessary parts of the code.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Bruno Peixoto
  • 211
  • 1
  • 4
  • 17

1 Answers1

4

Problem

Function findStatistics() is defined twice: in main and imageProcessing modules.

Reason

You did one or several of the following:

  • copy-pasted function's body into several source files
  • #included header file with function body in multiple modules and function is not inline
  • linked against a library which has a function with the same name as one of your functions or as a function from another library

Possible solutions

  • remove duplication by moving declaration of the function into header file and definition into source file
  • declare function as inline in header file (this is only a good idea if your function is "small". See: When should I write the keyword 'inline' for a function/method?)
  • move your function into namespace to avoid name collision
Community
  • 1
  • 1
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Thank you for the fast answer. – Bruno Peixoto Jun 04 '15 at 22:26
  • You linked to an answer that very much explains, when to use the `inline` keyword. Your recommendation to use it only, if a function is small, is bogus, and nothing in the linked answer even remotely hints towards that. In C++, `inline` is used exclusively as a linker hint. – IInspectable Jun 07 '15 at 09:59
  • @IInspectable Quote: "When should I write the keyword 'inline' for a function/method in C++? Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple compilation units. It's a good idea to define **small** (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time." End quote. Does it hint enough? – Ivan Aksamentov - Drop Jun 07 '15 at 12:25
  • Well, sorry, that's bogus. It's an opinionated recommendation, when to put functions right in a header (vs. an .inl-file, I assume). This is not at all related to the `inline` keyword. As I said before: `inline` is a linker hint, no more, no less. A function's LOC count does not ever serve as a predicate. – IInspectable Jun 07 '15 at 23:09
  • And when this same problem happens with variables? In special global variables. The advice worked well even though the functions I've wrote have normally approximately 80 lines. The situation is so defined: I've created a header to define all the global and define variables. To solve this problem of linkage, I've defined in this header a namespace to adequate the scope variables and avoid conflict with already declared ones. Despite of that the program keep telling the global i.e. define variables were already defined in another .obj file. – Bruno Peixoto Jun 08 '15 at 10:38
  • @Bruno: **Declaring** a variable requires the use of the `extern` keyword. Without this keyword you have a **definition**, and if this shows up in multiple compilation units your linker issues errors. If you need to use globals, put all your declarations in a header, e.g. *globals.h*: `extern int foo;`. The globals need to be defined in a single compilation unit, e.g. *globals.cpp*: `int foo;` – IInspectable Jun 08 '15 at 11:20
  • Ok than. I'm seeing how problematic can global variables be. And it will not even easy afterwards to understand the code. I'll try to use classes and references instead. Thank you, guys. – Bruno Peixoto Jun 08 '15 at 13:41
  • @IInspectable I don't understand what you are trying to say exactly. That I haven't explained inlining in details? It wasn't my goal. That linked answer with 294 upvotes is wrong? Seems a bit strange. Also, AFAIK, at least in case of major compilers with no LTCG enabled, inlining happens during compilation. It is not a linker hint. Could you please provide your opinion/knowledge in a form of corrections to my answer (instead of accusations), so we could improve it? – Ivan Aksamentov - Drop Jun 08 '15 at 13:41
  • The `inline` keyword is **ignored** by **all major C++ compilers** as far as actual inlining is concerned. The `inline` keyword serves as a linker hint **exclusively** in C++. Confusing as it may appear: `inline` has nothing to do with inlining. And, yes, an answer with 294 upvotes can be wrong. In fact, the more upvotes an answer receives the less reliable they become. Lot's of *"me, too"* voting. – IInspectable Jun 08 '15 at 13:52
  • @IInspectable I know that `inline` does not guarantee inlining. Never heard it's ignored or used by linker. Do you have some links to read about it? I'm still confused about how can I improve my answer. – Ivan Aksamentov - Drop Jun 08 '15 at 15:34