0
votes

I have 3 files

//--------------reg_des.h---------------
struct reg
          {
              unsigned int i : 4;
              unsigned int j : 4;
          };
extern struct reg; 



//--------------reg_des.c---------------

struct reg xyz_reg = {.i = 2,.j = 1};


//--------------main.c---------------
#include "reg_des.c"
void  display_onmodule(struct reg xyz_reg_1)

int main()
{
   display_onmodule(xyz_reg);
}

void  display_onmodule(struct reg xyz_reg_1)
{
     .....
 }

Here I have declared a struct in a header file and initialize variable of struct type in another source file. Actually I want to know is it right way to declare a struct which may be used by multiple source files?

1
extern struct reg; means nothing. To define a structure you need just the definition, as you made in the header, To declare an instance of such a structure you need the declaration, i.e. including the header. To access the instantiation xyz_reg of structure reg you must define it as extern struct reg xyz_reg; in the header file.Frankie_C
To access the instantiation xyz_reg of structure reg in different units (files) you must define it as extern struct reg xyz_reg; in the header file, and include the header in each source.Frankie_C
@Frankie_C Except, he shouldn't be doing that, because it is horrible program design.Lundin
@Lundin What is horrible: to define a structure and an extern reference in an header file? I made no mention, to be honest I haven't even notice it, that including C files in other C files is a good or bad idea.Frankie_C
@Frankie_C Yes, to use extern/global variables across multiple files is 100% bad practice. With the rare exception of const qualified ones.Lundin

1 Answers

0
votes

No, this is not the right way to design programs - this is spaghetti programming with global variables. There exists almost no case where global (non-const) variables are justified to use.

In addition, if you ever find a need to include a .c file, it means that your design has gone complete haywire. We only include .h files, ever.

The simplest way to fix your program is this:

//--------------reg_des.h---------------
#ifndef REG_H // always use header guards!
#define REG_H    

struct reg  // note: this bit-field is completely non-portable
{
    unsigned int i : 4;
    unsigned int j : 4;
};

void reg_init (struct reg* r);

#endif // REG_H


//--------------reg_des.c---------------
#include "reg_des.h"    

void reg_init (struct reg* r)
{
  *r = (struct reg) {.i = 2,.j = 1};
}




//--------------main.c---------------
#include "reg_des.h"

void  display_onmodule(struct reg xyz_reg_1);

int main()
{
   struct reg xyz_reg;
   reg_init(&xyz_reg);

   display_onmodule(xyz_reg);

   // pass on xyz_reg to x different files here, etc
}

void  display_onmodule(struct reg xyz_reg_1)
{
     .....
}

There are better designs still, with private encapsulation, but the above is acceptable.