jeudi 2 juillet 2015

Link error LNK2001 & LNK1169 in VS 2013 while compiling the C++ program - B. Stroustrup's PPP using C++: Ch. 8 - Q1 Drill?

Possible duplicate:
stroustrup ppp chapter 8 drill headers


I'm learning C++ using PPP using C++ by B. Stroustrup, 1st edition. I am having trouble solving this question, Ch. 8 Drill, Q1 -

Create three files: my.h, my.cpp, and use.cpp. The header file my.h contains

extern int foo;
void print_foo();
void print(int);

The source code file my.cpp #includes my.h and std_lib_facilities.h, defines print_foo() to print the value of foo using cout, and print(int i) to print the value of i using cout.

The source code file use.cpp #includes my.h, defines main() to set the value of foo to 7 and print it using print_foo(), and to print the value of 99 using print(). Note that use.cpp does not #include std_lib_facilities.h as it doesn't directly use any of those facilities.

Get these files compiled and run. On Windows, you need to have both use.cpp and my.cpp in a project and use { char cc; cin>>cc; } in use.cpp to be able to see your output.


I'm using Visual Studio 2013. Here are the files I created using the question -

my_8drill.h (my.h)

extern int foo;
void print_foo();
void print(int);

my_8drill.cpp (my.cpp)

#include "std_lib_facilities.h"
#include "my_8drill.h"

void print_foo()
{
    cout << foo << endl;
    return;
}

void print(int i)
{
    cout << i << endl;
    return;
}

use_8drill.cpp (use.cpp)

#include <iostream>      // Well, the question never mentioned to add "std_lib_facilities.h", 
                         // so I added this
#include "my_8drill.h"

using std::cin;

int main()
{
    foo = 7;
    print_foo();
    print(99);

    char c;
    while (cin >> c)
        if (c == 'q')
            break;
}

But these errors (link errors hopefully) occurred while compiling this program -

1>my_8drill.obj : error LNK2001: unresolved external symbol "int foo" (?foo@@3HA)
1>use_8drill.obj : error LNK2001: unresolved external symbol "int foo" (?foo@@3HA)
1>C:\Users\I$HU\Documents\Visual Studio 2013\Projects\C++ Development\Debug\C++ Development.exe : fatal error LNK1120: 1 unresolved externals

Then I remembered that extern int foo; is only a declaration, not a definition, so I need to define it somewhere, so I replaced extern int foo; with int foo; in the header file my.h.

But then again after compiling, these (link) errors occurred -

1>use_8drill.obj : error LNK2005: "int foo" (?foo@@3HA) already defined in my_8drill.obj
1>C:\Users\I$HU\Documents\Visual Studio 2013\Projects\C++ Development\Debug\C++ Development.exe : fatal error LNK1169: one or more multiply defined symbols found

So from the errors, I assumed that since there are two "my.h" headers, one in my.cpp and other in use.cpp, so I changed back int foo; in my.h to extern int foo; and added int foo; to use.cpp like this -

#include <iostream>
int foo;            // this line is new
#include "my_8drill.h"

and so foo won't get defined twice, and the program runs fine now, but still, these questions are bothering me again & again -

  1. Am I correct in my approach while resolving the above-mentioned errors ?
  2. (Extension to 1) Is there anything more to know (missing details) about these errors (I'm quite positive about this) ?
  3. Even if the program runs in the end, how do function-declarations in my.h know where their definition are (in my.cpp) ?
  4. (Extension to 3) How do they link up (my.h & my.cpp) with each other when I've only #included "my.h" to use.cpp ?
  5. How do just adding int foo; to my.cpp lets my.h know about the variable foo?

Please help me with these.

Here is the header file std_lib_facilities.h.

Aucun commentaire:

Enregistrer un commentaire