Hi,
I have a query regarding linking from object code. First pls go
through this
message. At the end of this I have the query.
I created the following 5 files in my home
directory; which are:-
header1.h,header1.cpp,header2.h,header2.cpp,main.h
------------------------
// header1.h
#include "header1.cpp"
class employee;
// header1.h ends
------------------------
// header2.h
#include "header2.cpp"
class company;
// header2.h ends
------------------------
// header1.cpp
#include <stdio.h>
class employee
{
char name[30];
float salary;
public:
employee() {};
~employee() {};
void display() { printf("\nthis is an employeeA\n"); }
};
// header1.cpp ends
------------------------
// header2.cpp
#include <stdio.h>
class company
{
char company_name[30];
int total_employees;
public:
company(){};
~company(){};
void display() { printf("\nthis is a companyA\n"); }
};
// header2.cpp ends
------------------------
// main.cpp
#include "header1.h"
#include "header2.h"
int main()
{
employee a,b,c;
company c1,c2,c3;
a.display();
c1.display();
return 1;
}
// main ends
------------------------
Then I did the following things.
I deleted demo.out. I generated object code for main.cpp,header1.cpp
and
header2.cpp using the following commands:-
aCC -c main.cpp header1.cpp header2.cpp
So at this stage I have main.o,header1.o and header2.o
So when I link these 3 object files it works fine and I get the
executable
with expected behaviour:-
aCC -o demo1.out main.o header1.o header2.o
This executable(demo1.out) prints the following:-
this is an employeeA
this is companyA
Then I deleted main.cpp. Then I changed the code of header1.cpp little
bit.
I just changed the printf statement, Not it should print "This is an
employeeB"
(instead of "This is an employeeA" ). Now since I have only changed
header1.cpp
I just recreated its object code using the following command:-
aCC -c header1.cpp
So at this stage we have the following object code (.o) files.
main.o (old)
header1.o (updated)
header2.o (old)
So then I tried to make new executables out of these 3 object files:-
aCC -o demo2.out main.o header1.o header2.o
So I have demo2.out now. NOW THIS IS THE QUESTION. Now since I have
created
the executable using the updated version of header1.o ; the executable
should print "This is an employeeB". But it still prints "This is an
employeeA".
So the output of demo2.out is the same as that of demo1.out. Why does
it happen?
I performed this small exercise to understand linking purely from
object code.
Thanks,
The Learner
|
|
0
|
|
|
|
Reply
|
dhiraj.nilange (2)
|
1/29/2007 1:25:57 PM |
|
learner <dhiraj.nilange@iflexsolutions.com> wrote:
> I have a query regarding linking from object code. First pls go
> through this message. At the end of this I have the query.
While there are no doubt a number of folks familiar with HP aCC
lurking in this group, you may want to try asking in comp.sys.hp.hpux
too.
When you do, be certain to include the rev of the HP-UX OS you are
running, as well as the rev of the aCC you are using, and any aCC
patches you may have installed on the system. Things like that are
almost always requested by folks when trying to work-out what might be
happening.
sincerely,
rick jones
--
oxymoron n, commuter in a gas-guzzling luxury SUV with an American flag
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
|
|
0
|
|
|
|
Reply
|
rick.jones2 (1065)
|
1/30/2007 1:41:32 AM
|
|
"learner" <dhiraj.nilange@iflexsolutions.com> writes:
> ------------------------
> // header1.h
> #include "header1.cpp"
> class employee;
> // header1.h ends
> ------------------------
> // header2.h
> #include "header2.cpp"
> class company;
> // header2.h ends
> ------------------------
> // main.cpp
>
> #include "header1.h"
> #include "header2.h"
>
> int main()
> {
> employee a,b,c;
> company c1,c2,c3;
> a.display();
> c1.display();
> return 1;
> }
> // main ends
> ------------------------
The code for employee::display() has now been inlined into main.o:
/usr/ccs/bin/nm -px main.o | grep display
# nothing.
> Then I deleted main.cpp. Then I changed the code of header1.cpp little
> bit. I just changed the printf statement, Not it should print "This is an
> employeeB" (instead of "This is an employeeA" ). Now since I have only changed
> header1.cpp I just recreated its object code using the following command:-
>
> aCC -c header1.cpp
There is no code in header1.o *at all*. So this command did nothing.
> So then I tried to make new executables out of these 3 object files:-
> aCC -o demo2.out main.o header1.o header2.o
>
> So I have demo2.out now. NOW THIS IS THE QUESTION. Now since I have
> created the executable using the updated version of header1.o ; the executable
> should print "This is an employeeB". But it still prints "This is an
> employeeA".
As it should, due to inlining.
If you want to prevent inlining, put class declaration into header1.h:
class employee
{
char name[30];
float salary;
public:
employee();
~employee()
void display();
};
and put member definitions into header1.cpp:
#include <stdio.h>
#include "header1.h"
employee::employee() { }
employee::~employee() { }
employee::display() { printf("whatever\n"); }
Now it will work the way you expect it to work.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
|
|
0
|
|
|
|
Reply
|
ppluzhnikov-nsp (516)
|
1/30/2007 3:48:18 AM
|
|
On Jan 30, 8:48 am, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:
> "learner" <dhiraj.nila...@iflexsolutions.com> writes:
> > ------------------------
> > // header1.h
> > #include "header1.cpp"
> > class employee;
> > // header1.h ends
> > ------------------------
> > // header2.h
> > #include "header2.cpp"
> > class company;
> > // header2.h ends
> > ------------------------
> > // main.cpp
>
> > #include "header1.h"
> > #include "header2.h"
>
> > int main()
> > {
> > employee a,b,c;
> > company c1,c2,c3;
> > a.display();
> > c1.display();
> > return 1;
> > }
> > // main ends
> > ------------------------
>
> The code for employee::display() has now been inlined into main.o:
>
> /usr/ccs/bin/nm -px main.o | grep display
> # nothing.
>
> > Then I deleted main.cpp. Then I changed the code of header1.cpp little
> > bit. I just changed the printf statement, Not it should print "This is an
> > employeeB" (instead of "This is an employeeA" ). Now since I have only changed
> > header1.cpp I just recreated its object code using the following command:-
>
> > aCC -c header1.cpp
>
> There is no code in header1.o *at all*. So this command did nothing.
>
> > So then I tried to make new executables out of these 3 object files:-
> > aCC -o demo2.out main.o header1.o header2.o
>
> > So I have demo2.out now. NOW THIS IS THE QUESTION. Now since I have
> > created the executable using the updated version of header1.o ; the executable
> > should print "This is an employeeB". But it still prints "This is an
> > employeeA".
>
> As it should, due to inlining.
>
> If you want to prevent inlining, put class declaration into header1.h:
>
> class employee
> {
> char name[30];
> float salary;
> public:
> employee();
> ~employee()
> void display();
>
> };
>
> and put member definitions into header1.cpp:
>
> #include <stdio.h>
> #include "header1.h"
>
> employee::employee() { }
> employee::~employee() { }
> employee::display() { printf("whatever\n"); }
>
> Now it will work the way you expect it to work.
>
> Cheers,
> --
> In order to understand recursion you must first understand recursion.
> Remove /-nsp/ for email.- Hide quoted text -
>
> - Show quoted text -
Hi Paul ,
Thanks for that. I tried that way. I have moved declarations to
header( .h) files and definition in source (.cpp) files. It looks as
shown below.
--------------------header1.h-----------------
class employee
{
char name[30];
float salary;
public:
employee(){};
~employee(){};
void display();
};
-----------------header1.cpp---------------------
#include <stdio.h>
#include "header1.h"
employee::employee(){}
employee:;~employee(){}
void employee::display() { printf("\nthis is an employeeA\n"); }
------------------header2.h------------------------------
class company
{
char company_name[30];
int total_employees;
public:
company(){};
~company(){};
void display();
};
--------------------------header2.cpp---------------------
#include "header2.h"
#include <stdio.h>
company::company() {}
company::~company() {}
void company::display() { printf("\nThis is a companyA\n"); }
-----------------------------
main.cpp-----------------------------------
#include "header1.h"
#include "header2.h"
int main()
{
employee a,b,c;
company c1,c2,c3;
a.display();
c1.display();
return 1;
}
-----------------------------------------------------------------------
----
BUT now when I try to comile it I get the following error:-
$ aCC -c main.cpp header1.h header2.h
"header2.cpp", line 3: catastrophic error #2003: #include file
"header2.h"
includes itself
#include "header2.h"
^
1 catastrophic error detected in the compilation of "main.cpp".
Compilation terminated.
I tried a doing it with header1.cpp and header2.cpp also just to
test ; but for that also I get error:-
$ aCC -c main.cpp header1.cpp header2.cpp
main.cpp:
"header2.cpp", line 3: catastrophic error #2003: #include file
"header2.h"
includes itself
#include "header2.h"
^
1 catastrophic error detected in the compilation of "main.cpp".
Compilation terminated.
header1.cpp:
"header1.cpp", line 6: error #2302: function "employee::employee()"
has
already been defined
employee::employee(){}
^
"header1.cpp", line 7: error #2040: expected an identifier
employee:;~employee(){}
^
"header1.cpp", line 7: error #2169: expected a declaration
employee:;~employee(){}
^
At end of source: warning #2012-D: parsing restarts here after
previous syntax
error
3 errors detected in the compilation of "header1.cpp".
header2.cpp:
"header2.h", line 3: catastrophic error #2003: #include file
"header2.cpp"
includes itself
#include "header2.cpp"
^
1 catastrophic error detected in the compilation of "header2.cpp".
Compilation terminated.
How should I go about it??
Thanks
-L
|
|
0
|
|
|
|
Reply
|
dhiraj.nilange (2)
|
1/30/2007 6:09:13 AM
|
|
"learner" <dhiraj.nilange@iflexsolutions.com> writes:
> On Jan 30, 8:48 am, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
Please learn to trim your replies.
> class employee
> {
> char name[30];
> float salary;
> public:
> employee(){};
> ~employee(){};
> void display();
> };
> -----------------header1.cpp---------------------
> #include <stdio.h>
> #include "header1.h"
>
> employee::employee(){}
> employee:;~employee(){}
> void employee::display() { printf("\nthis is an employeeA\n"); }
This is invalid code -- you provided two definitions of
employee::employee(), and there is *no way* this code:
employee:;~employee(){}
will compile.
Don't "transcribe" what you did, cut/paste it instead.
> BUT now when I try to comile it I get the following error:-
>
> $ aCC -c main.cpp header1.h header2.h
Compiling *.h files is a bad idea.
Compile *.cpp files instead.
> "header2.cpp", line 3: catastrophic error #2003: #include file
> "header2.h"
> includes itself
> #include "header2.h"
It's obvious that the code you've tried to compile doesn't match
your description above.
According to the compiler, your header2.h (line) still contains
"#include "header2.h"'. You can't do that (for obvious reason).
> How should I go about it??
Engage brain?
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
|
|
0
|
|
|
|
Reply
|
ppluzhnikov-nsp (516)
|
1/31/2007 3:35:06 AM
|
|
On Mon, 29 Jan 2007, learner wrote:
>
> Hi,
>
> I have a query regarding linking from object code. First pls go
> through this
> message. At the end of this I have the query.
>
> I created the following 5 files in my home
> directory; which are:-
> header1.h,header1.cpp,header2.h,header2.cpp,main.h
^^^^^^
You probably meant main.cpp-------------------+
> So the output of demo2.out is the same as that of demo1.out. Why does
> it happen?
There are several prolems with your code. Let me explain them to you
step by step. If you passed the following command line to your linker:
aCC -o demo3.out main.o
(i.e. you do not pass the header1.o or header2.o files to it)
you would have noticed that your program linked successfully, without any
complaining on undefined symbols. This happens because you are not
actually performing separate compilation of object files and linking the
object files together; instead you are including (albeit indirectly) the
file header1.cpp and header2.cpp into main.cpp. Therefore main.o will
contain the compiled code of employee::display() and company::display().
So the linker does not need to use header1.o and header2.o at all. Both
these files contain another version of employee::display(), respectively
company::display(), but the linker will not look at them to resolve
symbols, because like I said, main.o already includes the definition of
those functions.
There is also a more subtle point here: since you wrote
the body of the member function (display) inside the class definition
(Employee, and Company), C++ will imply that the function is defined as
inline, which in C++ means that it has static linkage. Therefore the
linker will not complain about multiply defined symbols (both in main.o
and header1.o, respectively header2.o)
The way you wrote your code (i.e. #including .cpp files) is very bad
programming practice, you must consult a good C++ book for how to do this
correctly.
Here is a modified version of your code, which should work how you expect
it. I have also renamed the files to be slightly more meaningful:
//employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class employee {
public:
employee(void);
~employee(void);
void display(void);
private:
char name[30];
float salary;
};
#endif /* EMPLOYEE_H */
//-------End of employee.h
//company.h
#ifndef COMPANY_H
#define COMPANY_H
class company {
public:
company(void);
~company(void);
void display(void);
private:
char company_name[30];
int number_of_employees;
};
#endif /* COMPANY_H */
//-----End of company.h
//employee.cpp
#include <stdio.h>
#include <string.h>
employee::employee(void)
:salary(0.0f)
{
strcpy(name,"");
}
employee::~employee() {}
void employee::display(void)
{
printf("This is Employee A\n");
}
//---End of employee.cpp
//company.cpp
#include <stdio.h>
#include <string.h>
company::company(void)
: number_of_employees(0)
{
strcpy(company_name,"");
}
company::~company(void)
{
}
void company::display(void)
{
printf("This is Company A\n");
}
//---End of company.cpp
main.cpp remains unchanged except for replacing "header1.[h,cpp,o]" and
"header2.[h,cpp,o]" with "employee.[h,cpp,p]" respectively
"company.[h,cpp,o]"
If you have more questions, feel free to ask, but I think that your
problem is related to C++ and has little to do with UNIX if at all. Such
questions are better asked in a C++ specific newsgroup.
Emil
>
> I performed this small exercise to understand linking purely from
> object code.
>
> Thanks,
> The Learner
>
>
|
|
0
|
|
|
|
Reply
|
emild2 (25)
|
2/2/2007 3:42:42 PM
|
|
|
5 Replies
38 Views
(page loaded in 0.144 seconds)
|