Linking errors

I do not have any idea why this will not link under win98 using VC6.0.  This program runs fine under UNIX using g++ and I am trying to port it to the win platform.  If you want to look at the program it is available at
members.xoom.com/fatbooda/cppcode/L2.zip

If you can figure out what is wrong with it or a better way to support strings let me know.  My email is fat_booda_belly@yahoo.com.

Thanks
LVL 1
boodabellyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mikeblasCommented:
You misspelled the URL. The file really is at:

http://members.xoom.com/fatbooda/cppCode/L2.zip.

The problem is that you're using the #include directive to reinclude C++ code over and over again. For each *.CPP file that #includes another *.CPP file, you get the symbols redefined. When the linker gets all the OBJs together, it can't resolve any of the functions becuase you've defined them all more than once.

You need to write header files that provide declarations for your structures and functions. Give those files a *.H extension, and set things up so that each module which declares some symbols has a match *.H file.  For instance, write a STRINGMF.H file that declares everything which is defined in your STRINGMF.CPP file.

Then, #include the "stringmf.h" file, not stringmf.cpp!

If you want me to do it for you, and send the project back, increase the points to 250.

..B ekiM
0
mikeblasCommented:
It seems like you _Tried_ to get this done, but somehow got confused and fell short.  StringCL.CPP is what should be in STRINGMF.H.  Everything should #include "stringmf.h". Then, you should still have stringmf.cpp build and be linked into your executable.

All the #ifdef/#endif hacks you tried to get this to work should be deleted.

..B ekiM
0
cyberfrankCommented:
Hi!

The basic problem is, that You put those source files too to the source files list which are NOT CPP sources, they are headers. You simply remove header cpp files from the list and the linking problem will be solve.
Think a little bit! Try to understand what the Visual C++ 6.0 project handler will do! It will compile all source files in the "Sources" list, so You will have duplicates. So, simple remove header cpp files (or move it to the headers list!!!), ie. All files which ends whith *CL.cpp all put they all into the headers list. Itt will work!
One more thing. You have to replace in ALL *CL.cpp files the include files which are ending whit *MF.cpp and You have to use *CL.cpp instead!!!!!!

If You tell me an e-mail address I'll send You the edited project, so You can learn ;-)
BTW: Lot of things are different is VC than in g++
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

cyberfrankCommented:
PS: You can download Your edited and working project from:
http://www.inf.u-szeged.hu/~magyar/l2.zip
0
boodabellyAuthor Commented:
I just dl'd the file and Im looking at it right now while I am at work.  VC is sooo much different than a UNIX enviroment.  My prof said that g++ was the most up to date compiler that is available but from my experience and what I have read I think that he is mistaken.  Give me a little while to look at this and then I will accept the answer.  Thank you very much for you help.

Oh by the way, the prof has us put everything in .cpp instead of .h so the compiler can compile them.  also why do you not need to conditionally compile each file with the #ifndef statements.  I think I am getting confused on the proper way to include file in VC.  Its alot different than g++.
0
mikeblasCommented:
Nice steal, cyberfrank.

..B ekiM
0
mikeblasCommented:
> Oh by the way, the prof has us put everything in .cpp instead
 > of .h so the compiler can compile them.

That's wrong. If that's really what your prof has told you, he doesn't know what he's talking about.

The compiler compiles *.CPP files. It includes *.H Files. If your program is split into different *.CPP files and code in each *.CPP file references stuff in other *.CPP files, you'll need to provide *.H Files to describe the content of each *.CPP file.  You _don't_ include the other *.CPP File.

 > also why do you not need to conditionally compile
 > each file with the #ifndef statements.

The conditionals you've inserted are useless, anyway. They'd prevent a file from beeing seen by the compiler more than once per invocation of the compiler.  If you did this (or the equivalent) in your source,

   #include "foo.h"
   #include "foo.h"

that #ifndef/#define/#endif mechanism you're using would stop the 2nd directive from seeing the content of foo.h again. In your code, you never do this.

The #ifndef/#define/#endif trick does _not_ stop you from bulding some code in two different invocations of the compiler and then tryint to link the resulting, redunant object code into an executable image.

 > 1I think I am getting confused on the proper way to
 >include file in VC.  Its alot different than g++.

It shouldn't be. This technique is for C++, no matter what compiler you're using.

..B ekiM
0
boodabellyAuthor Commented:
the way that the prof designed for the program to be setup was:
driver:
#include programmer
#include admin
#include tester
#include sales

sales, admin:
#include manager

programmer, tester:
#include manager

manager, developer:
#include employee

employee:
#include constants

I dont know if this is the best way to do this, but this is how we have to do this for the class
0
mikeblasCommented:

 > I dont know if this is the best way to do this,
 > but this is how we have to do this for the class
 
#including the *.CPP code is the wrong thing to do. Let me add file extensions to these things to make it clear:

from the driver.cpp file:
#include programmer.h
#include admin.h
#include tester.h
#include sales.h

from the sales.cpp, and admin.cpp files:
#include manager.h

from the programmer.cpp, and tester.cpp files:
#include manager.h

from the manager.cpp and developer.cpp files:
#include employee.h

from the employee.cpp file:
#include constants.h

The *.H files should include declarations, only. The *.CPP files should include defintions, only. Actual executable code shouldn't show up in the *.H files.

..B ekiM
0
boodabellyAuthor Commented:
mikeblas,
I will make another question for you to answer for the points also.  I just appreciate the help and want to learn this language, along with c that is.

ok I am confused then.  If driver includes admin and sales, and admin and sales includes manager.  Then wont manager be included twice, once from the admin include and once from the sales include, or does VC know better?

Also if you would like to help me clean this app up in your spare time and turn it into a windows app that uses win32 controls to make a somewhat decent app that I can learn from it would be greatly appreciated.  If you do email me and let me know how many points you want for your time.  I only have 1400 points currently, so I cannot offer anymore than that.  Thank you very much for you time and patience with the new people
0
mikeblasCommented:

 > ok I am confused then.  If driver includes admin and sales,
 > and admin and sales includes manager.  Then wont manager
 > be included twice, once from the admin include and once
 > from the sales include, or does VC know better?

The way you have it coded right now, yes--that's exactly what's happening, and that's why you get all the multiply defined errors.  You're getting a single error for each extra instance of every function you have in every module that's included more than once!

You're not reading my responses: you need to put only declarations in the *.H files. A declaration for a class or function or bit of data includes no code. But it _does_ give the compiler enough information to reference that data, create the class, or make a call to the declared function. For all of those things, the referencing code the compiler generates doesn't need to know the whole function or class--it just needs to know what it looks like.

The stuff in your *.CPP files produces the actual definitions. Those need to show up only once in your whole module.

I pointed this out before with a more specific example. What you have in STRINGCL.CPP in your project should be in STRING.H. It includes only the definition of the class and no code.  What you have in STRINGMF.CPP should be in STRING.CPP. It implements the string class you wrote. If you have some other code, say, in MANAGER.CPP, that wants to use the string class, it needs only to #include "string.h", not to #inlcude "string.cpp".

..B ekiM
0
mikeblasCommented:
> help me clean this app up in your spare time and
 > turn it into a windows app that uses win32

I'm sorry; I can't. I just don't have that much spare time to give away.

..B ekiM
0
boodabellyAuthor Commented:
yeah I change all those to what you suggested.  I was just going by what my professor told me.

If you #include a header file in more than one place, the program will not link correctly, right?
0
cyberfrankCommented:
>If you #include a header file in more
>than one place, the program will not
>link correctly, right?

Hi!

Not exactly. The main problem  was, that You include not only the header files, then files which contained the class member functions definitions too (i.e. #include stringMF.cpp)
In this case in each compilation unit will be present the string class function definition and the  will result a linker error. I doesn't mather that You have put #ifdef... #endif pair on front and at the end of *MF.cpp file, beacuese in each compilation unit i.e. stringMF.cpp it will included ONE time, but in whole project (when linker approaches) itt will be included a 10 time or more. A One compilation unit is one cpp file in sources list for which the compiler will produce an obj file.
I hope You understand.

CF
             
0
cyberfrankCommented:
Just a comment:
>Oh by the way, the prof has us put
>everything in .cpp instead of .h so
>the compiler can compile them.  

He is maybe Pascal oriented?

CF
0
mikeblasCommented:
> He is maybe Pascal oriented?

Pascal is not C++. For what university tuition costs these days, you think he'd be able to remember that.

..B ekiM
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.