0

I have two files, main.ccp and namespace.cpp (Not the actual names, but for simplification)

My namespace.cpp can be boiled down to the following:

#pragma once
namespace MyNamespace {
    int A = 0;
}

And my main.cpp basically just uses the content of MyNamespace:

#include "namespace.cpp"
int main() {
    ...
    // Using MyNamespace::A
    ...
}

But I keep getting a LNK2005 error in MyNamespace.obj, that A is already defined in main.obj.

Which is weird: It's not like I've defined it twice. I'm literally just using it in my main file, but since I wanted to clean up my main file a little bit I put it into it's own file and into a namespace.

I don't understand where the problem is, would appreciate help. Thanks

Fly
  • 810
  • 2
  • 9
  • 28
  • 2
    Fyi, `#include "anything.cpp"` is an automatic design smell. My crystal ball tells me `namespace.cpp` is included already as part of your project build (ok, that's not really my crystal ball; clearly it is being compiled separately since you stated the link error specifically mentioned `MyNamespace.obj` ; that object code file didn't arise out of thin air). Therefore including it *again* by preprocessor duplicates its symbols in multiple units, and thus duplicate link-time symbols. – WhozCraig Mar 26 '21 at 20:39
  • 1
    Why `#include "namespace.cpp"`? Including .cpp files is, almost always, a wrong thing to do (one even could argue, that it is **always** a mistake). – Algirdas Preidžius Mar 26 '21 at 20:40
  • _"It's not like I've defined it twice"_ It is _very likely_ that you're compiling that code twice. But that detail has been left out of your question. – Drew Dormann Mar 26 '21 at 20:44
  • I suspect the *original* problem you're trying to solve was, without the `#include` aforementioned, `main.cpp` would not compile because it has no idea what `MyNamespace` and/or `MyNamespace::a` is. You need a header. In said header you need `namespace MyNamespace{ extern int A; }` (properly guarded, of course). Include *that* in `main.cpp` and you'll probably be off to the races. – WhozCraig Mar 26 '21 at 20:45
  • So basically I usually only deal with classes, but felt like OOP was not the right way to go about the particular thing that I'm doing this time, and just wanted to put it in a different file to clean up my main file. I initially had a namespace .h and .cpp file and included the h file only but that still gave me the same error – Fly Mar 26 '21 at 20:45
  • @WhozCraig I did initially have a .h, but it gave me the same error, so I thought since I'm not using classes I would not need the .h definitions after all (basically I'm thinking the include just copy pastes the code of my cpp, is that wrong?) Why would I need the extern keyword though? Like, all of the variables and functions in my namespace are only used in my main file, and nowhere else – Fly Mar 26 '21 at 20:48
  • Different topic. One (the .cpp file) defines the existence of something; the other (the .h *as I described it*) declares said existence, but professes the actual definition is somewhere else. You can only have one formal definition. In fact, there is literally a rule for it (ODR : one definition rule). The fastest way to fix this is to do *exactly* as I described earlier. Define that header file *exactly* as I showed (adding include-guards is probably a good idea too), and include that, not the .cpp, in `main.cpp`. That's one .h, two .cpp's, and it should be good. – WhozCraig Mar 26 '21 at 20:50
  • Typo. MyNamespace isn't the same as MyNameSpace; – Jim Castro Mar 26 '21 at 20:50
  • @JimCastro Sorry, I made a typo in the post. – Fly Mar 26 '21 at 20:51
  • @WhozCraig That's how I usually did use it as well. I just thought that there was no point in a header since I just included the file once, but I guess I was thinking wrongly. Would you mind elaborating on why using extern would fix my error? I've read this: https://stackoverflow.com/questions/10422034/when-to-use-extern-in-c but it just feels weird that I need to have a (somewhat) more complicated setup when all I wanted to do was outsource some procedural code into a namespace in a different file. – Fly Mar 26 '21 at 20:55
  • I already did. *"One (the .cpp file) defines the existence of something; the other (the .h as I described it) declares said existence, but professes the actual definition is somewhere else."* – WhozCraig Mar 26 '21 at 20:56
  • @WhozCraig But why does the actual definition of *variables* need to be somewhere else? When I have a class, my header might be class A{int B;void C();}, but the implementation file will just contain void A::C(){}, and doesn't need to redefine B. Do I just need to redefine it because I'm using a namespace instead of a class? – Fly Mar 26 '21 at 21:01
  • I admit, I tried to follow your example, and couldn't. *Yes*, the definition of an referenced entity must be *somewhere*. and it can only be in *one* somewhere (ODR). Your error was a violation of ODR. Whether its a namespace or a class makes no difference. Your class example doesn't have to "redefine" `B` because it is a *member* variable. It doesn't exist without an instance of `A` (or a derivation of said same). – WhozCraig Mar 26 '21 at 21:19
  • @WhozCraig Ah, that makes sense, thanks. When I add extern keywords it does get rid of the Linker errors... But gives me the following errors instead: `Simulation.cpp(19,19): error C2374: 'Simulation::k': redefinition; multiple initialization. Simulation.h(27): message : see declaration of 'Simulation::k'`, where I have `extern float k;` in my Simulation.h, and `float Simulation::k = 0.f;` in my .cpp file... The .h file, which does have include guards, gets included in my main class. I thought I followed the way of doing it correctly now, but apparently not :/ – Fly Mar 26 '21 at 21:41
  • @WhozCraig Nvm, got it fixed, thanks! – Fly Mar 26 '21 at 21:58

0 Answers0