Path: chuka.playstation.co.uk!scea!greg_labrec@interactive.sony.com From: "Wayne K. Werner" Newsgroups: scea.yaroze.programming.codewarrior Subject: Re: tanttank demo linking problem in CW Date: 8 Sep 1997 04:44:42 GMT Organization: WermX Software Lines: 98 Message-ID: <01bcbc11$baf64960$9fbf43ce@wkwerner> References: <3412F639.5F1C6C64@zicorp.com> NNTP-Posting-Host: port59.con2.com X-Newsreader: Microsoft Internet News 4.70.1161 TJ Yang wrote: > tantank has no problem in and linking and compiling in GNU dos > environment. > In CW, compliation was fine but I got tons of error when linking the > object file together. > > The error messages are all about some variables are multipled defined. TJ, I investigated and found the problem. The question is not why the demo didn't link in CW, but why did it link at all in GNU? And, after linking, how did it run? First, when compiling under CW, several warnings were given for unused automatic variables in functions in different modules. Delete those lines defining the unused variables to remove these warnings. Also, main and another function (I forget the name) don't return values. The two funcs in question are not defined with a return type, a bad practice of lazy programmers. Add the void specifier to the front of the function definitions to remove these warnings. Finally the sticky problem. At the beginning of table.h, the following conditional compilation code appears: #ifndef __TABLE_C__ #define EXTERN #define __TABLE_C__ #else #define EXTERN extern #endif After this comes several declarations such as: EXTERN some_type some_name; It appears that the programmer was intending to use conditional comp to cause the variables to be defined in one module and declared in all others. (A definition creates the actual variable, whereas a declaration lets the compiler know that a variable of this name and type is defined elsewhere.) He hoped that the EXTERN line would be resolved once as: some_type some_name; and everywhere else as: extern some_type some_name; The programmer thought that the #define __TABLE_C__ would be in effect for all other modules compiled after the first module including the header. At least it appears that this is what he had in mind. This, however is not the case. #defines are in effect only in the current module being compiled. In every module the conditional compilation will resolve to: #define EXTERN #define __TABLE_C__ This will cause the variables to be *defined* in every module that includes table.h! I fixed the problem with the following method. In main.c, before the includes, I added the line: #define __MAIN_C__ In table.h I commented out the incorrect conditional comp and replaced it with: #ifdef __MAIN_C__ #define EXTERN #else #define EXTERN extern #endif Thus, only in main.c will we get a definition, all other modules including table.h will get declarations. The code compiles and links smoothly after this. I have not executed it to determine if it runs correctly or not. Many times in converting sample code from a GNU project to CW, I find that CW is catching many problems that GNU doesn't even notice. This was the case in the Survival Demo used in the auditorium presentation. CW found some instances of the use of uninitialized variables in one of the functions. The GNU compiler missed this totaly! If Pradip was using CW instead of GNU, he would have found these bugs before posting the demo. This is NOT a problem with CW, just the opposite! It appears that CW is the more robust compiler/linker by far. Good luck -- Wayne K. Werner wkwerner@con2.com