1

Because I'm still learning and am pulling my hair out trying to figure out why my linker keeps giving me problems, I'm been testing some stuff.

Here's what I did:

  • Make one.cpp and declare int myVar.

  • Make two.cpp and leave it empty.

  • Make two.h and declare int myVar.

  • include two.h into both one.cpp and two.cpp.

When I try to build it my linker says int myVar is already defined.

I know that you can only define stuff once but in this case I haven't double defined anything, just declared them.

Edit: If I add the 'extern' keyword to int myVar in two.h it works, but why should I have to? I'm really not understanding how this works.

Edit (A long time later): I am in fact defining the same variable multiple times.

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • I think I'm closer to the answer. one.cpp includes two.h (which has a declaration of var_b,) so one.cpp has a declaration of var_b. Then two.cpp includes the var_b declaration in the two.h file. Then when it comes time to link the two obj files, one already has the declaration and it's linking another one? But I thought you can declare as many times as you want but just not define more than once??? – Zebrafish Apr 02 '15 at 16:07

1 Answers1

3

Well a very long time later now I've understood the problem. When you do:

int a;    // <--- This is a definition, not just a declaration

It turns out there's a pretty elaborate system of rules in C++ about what constitutes a definition or declaration.

The following is an outline:

//  VARIABLES / BUILT-IN TYPES / PRIMITIVE DATA TYPES
int anInt;          // A definition
int anInt;          // Error, multiply defined variable, whether in same .cpp or another
extern int anInt;   // A declaration
extern int anInt;   // Fine, declare how often you like
int* pToInt         // A definition
extern int* pToInt  // A declaration
                    // Other types such as enums, references, etc. also fall in this category

// FUNCTIONS
// Keyword 'extern' is optional or doesn't do anything before a function declaration / signature without a body. Functions without a body can be declared as many times as you want, just like extern variables. Note, placing the 'inline' keyword before the function allows you to define it in multiple places. If multiply defined in the same cpp it must have the same implementation, otherwise the compiler won't notice different implementations in different cpps. This is confusing.
void shootSoldier();        // Function declaration, also signature or prototype
extern void shootSoldier(); // 'extern' keyword here makes no difference, it's optional
void shootSoldier();        // Same function can be declared again, no problem
void shootSoldier() {}      // Function has a function body, meaning it's defined.
void shootSoldier() {}      // Error: multiple definitions for function

// CLASSES / STRUCTS / USER-DEFINED TYPES
// Keyword 'extern' I'm pretty sure is optional or doesn't do anything before one of these types that doesn't have squiggly brackets, ie., isn't defined
struct Animal;          // Declaration of a type
extern struct Animal;   // No difference, declaration of a type
struct Animal;          // Repeated declaration, no problem
struct Animal{ string colour; }; // Definition of a type

//There is an extra rule with this last category. This category is most similar to the function category, but whereas functions can only be defined once in your program (meaning having a function body), with this category, classes, structs etc, you can only redefine it in another compilation unit, ie., another.cpp file.
// So:

struct Animal { string colour; };
struct Animal { string colour; };   //   Only allowed to redefine in another .cpp file

// Strangely, this seems to mean you can 'redefine' these types, meaning an exemption from the one definition rule (ODR).
// Then there's a whole mess of ifs and buts, like the fact that your class is defined, but the member function that it contains is only declared.
// There's no doubt more exceptions and subleties that I don't get.
// This topic has been covered a few times here at Stack Overflow.

http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration
Zebrafish
  • 11,682
  • 3
  • 43
  • 119