Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using extern keyword for user defined types in c++

Tags:

c++

extern

I want to use extern keyword for user defined types. This means I've declared object in one file and defined it in other file. I've read that extern keyword is used to declare the variable without defining it. extern keyword is useful when program is split into multiple source files and global variable needs to be used by each of them. Please correct me If I am wrong somewhere.

Here is the programs I've written but unfortunately I am doing something wrong or missing something so I am getting compiler errors.

Prog1.cpp

#include <iostream>
using std::cout;
class test
{
     public:
     void fun();
};
void test::fun()
{
    cout<<"fun() in test\n";
}
test t; 

Prog2.cpp

#include <iostream>
using std::cout;
extern test t;
int main()
{
    t.fun();
}

Now when I compile these 2 using

g++ -o prog1.cpp prog2.cpp

compiler gives me following errors in prog2.cpp

error: 'test' does not name a type

error:  't' was not declared in this scope

Please help me to know what I've done wrong here.

like image 356
Destructor Avatar asked May 29 '15 16:05

Destructor


2 Answers

extern tells the compiler that the definition of t is somewhere else, but the compiler still needs the defintiion of test, as you're using t.fun() to compile Prog2.cpp.

So the solution is, write test.h where you define the class, and then define test t in Prog2.cpp as usual. Include test.h in your Prog2.cpp so that it may know the definition of test. Then build it.

test.h:

#include <iostream>

using std::cout;

class test  //definition of test
{
     public:
     void fun()
     {
        cout<<"fun() in test\n";
     }
};

Prog1.cpp:

#include "test.h"

test t;  //definition of t

Prog2.cpp:

#include <iostream>

#include "test.h"

using std::cout;

extern test t; //the definition of t is somewhere else (in some .o)
               //and the definition of test is in test.h
int main()
{
    t.fun();
}

Now your code should compile and link.

Note that the definition of t is needed by the linker at link-time, so it will search for it in other .o files, but the definition of test is needed by the compiler, at compile-time.

Now it should be obvious that you can put the extern test t; in the header itself so that you dont have to write it in every .cpp file where you want to use the object defined in Prog1.cpp file (which is turned into Prog1.o by the compiler).

like image 166
Nawaz Avatar answered Sep 18 '22 16:09

Nawaz


Put the extern keyword in the header, not the cpp file. It is the job of the header to tell the compiler there is an externally defined object somewhere.

For example:

program.h (mostly declarations)

struct UserDefinedType
{
    void do_stuff();
};

// declare your global object in the header
// so that the compiler knows its name when
// compiling sources that can not otherwise see
// the object
extern UserDefinedType global_udt;

program.cpp (mostly definitions)

#include "program.h"

// define the member functions here
void UserDefinedType::do_stuff()
{
}

// define the global object here
UserDefinedType global_udt;

main.cpp (use the definitions that have been declared in the header)

#include "program.h" // tells the compiler about global_udt

int main()
{
    // call the global object that is defined
    // in a different source file (program.cpp)
    global_udt.do_stuff();
}

NOTE: If we didn't declare the object global_udt in the header file then main.cpp would not know of its existence and the compiler would complain if we tried to use it.

So the header needs to only declare the object and not define it hence the extern keyword is needed.

like image 23
Galik Avatar answered Sep 21 '22 16:09

Galik