Hello, I am using the PK51 package. My program requires a structure of arrays. The following files are used:- 1) declare.c For defining the global variables 2) declare.h Containing the extern definations of all the variables declared in declare.h This file will be used by all the c source files 3) main.c The main C source file 4) sub.c Containing some of the functions used by main.c The contents of each of the files are as under: file: declare.c struct param { float value[10]; char mode[10]; }; struct param a; int i; file: declare.h struct param { float value[10]; char mode[10]; }; extern struct param a; extern int i; file: main.c #include <reg51.h> #include "declare.h" main() { i = 0; initstruct(); } file: sub.c #include <reg51.h> #include "declare.h" void initstruct() { for (i=0;i<=9;i++) { a.value[i] = 2.5; a.mode[i] = 1; } } I have used two approaches to build the target files: 1) including the declare.h file in main.c and the sub.c file and compiling the main.c file and the sub.c file independently. Then linking the object files generated thereby. 2) Including the declare.c and sub.c file within main.c file and ignoring the declare.h file and then compiling and linking the main.c file independently. I am facing two problems with the above approaches: i) On using the above files and including all the .c files in the target build, the structure 'a' is not initialised properly. It is observed that the address calculations for the a.value and a.mode are not done properly. If I include the declare.c and the sub.c file in main.c file and do not use the declare.h file, the structure is initialised properly. What am I doing wrong with the first approach? 3) On using the first approach, the UVision2 debugger works alright. On calling the initStruct() routine, the control shifts to the sub.c file. But on using the second approach, I am unable to single step in the sub.c file The control cannot be seen in the sub.c file. One can only see the control in the assembly listing. How can I see it in the sub.c file also? Regards, Mohit
If your style is to place all globals in one large declare.h file. Try this approach. In the Main.c add:
#define DECLARE #include "declare.h"
#include "declare.h"
//Declare.h #ifdef DECLARE #define EXTERN #else #define EXTERN extern #endif struct param { float value[10]; char mode[10]; }; EXTERN struct param a; EXTERN int i;
Or, take a look at the following URL: http://www.keil.com/support/docs/1868.htm Jon
Go back to my original reply! You have definitions of 'struct param' in both declare.c and declare.h - this is bad: you have no guarantee that they're the same! a simple typo in one will cause you all sorts of grief elsewhere! Put the 'struct param' definition in one place only, and always use that one definition. Thus the definition should be in declare.h, and anything which needs to refer to 'struct param' should #include declare.h. Remove the 'struct param' definition from declare.c Strictly, your files should be called "declare.h" and "define.c," since the Header (.h) file contains variable declarations, whilst the .c file contains variable definitions. You should #define your array sizes, rather than use "magic numbers" and rely on remembering to subtract 1 where required.
//declare.h #define SIZE 10 struct param { float value[SIZE]; char mode [SIZE]; }; extern struct param a; extern int i;
//define.c #include "declare.h" struct param a; int i; // Why is this global, as it's only used for a loop counter?
//main.c #include "declare.h" main() { i = 0; // Unnecessary, as the initstruct() loop initialises i initstruct(); // Wot? No prototype! }
//sub.c #include "declare.h" void initstruct() { for (i=0; i<SIZE; i++) { a.value[i] = 2.5; a.mode [i] = 1; } }
There is nothing wrong with having
// header.h extern int i;
// file.c #include "header.h" // Contains an extern declaration of 'i' int i; // definition of 'i'
No don't. Do it the C way:
/* NastyGlobals.c */ #include "NastyGlobals.h" /* Actually define storage */ int g_yuckyOne; int g_yuckyTwo[100]; struct Thing g_thing; /* NastyGlobals.h */ #ifndef NastyGlobals_h_Included #define NastyGlobals_h_Included /* Declare objects to other modules */ struct Thing { char nameStr[128]; int id; }; extern int g_yuckyOne; extern int g_yuckyTwo[]; extern struct Thing g_thing; #endif