0

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?

Clíodhna
  • 818
  • 1
  • 15
  • 29
Gaurav Kumar
  • 31
  • 1
  • 3
  • `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 Nov 10 '17 at 12:15
  • 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 Nov 10 '17 at 12:22
  • @Frankie_C Except, he shouldn't be doing that, because it is horrible program design. – Lundin Nov 10 '17 at 12:23
  • @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 Nov 11 '17 at 15:50
  • @Frankie_C Yes, to use extern/global variables across multiple files is 100% bad practice. With the rare exception of `const` qualified ones. – Lundin Nov 13 '17 at 07:45
  • @Lundin This is really the very first time I hear that. Maybe I misunderstood the sense. I would be very glad if you clarify. – Frankie_C Nov 13 '17 at 08:38
  • @Frankie_C Umm... the (mis)use of global variables is one of the most frequently debated things in programming, a debate pretty much impossible to miss and therefore every programmer knows about it. It is generally addressed by any programming language beginner class. Examples: [Are global variables bad?](https://stackoverflow.com/questions/484635/are-global-variables-bad), [When is it ok to use a global variable in C?](https://stackoverflow.com/questions/176118/when-is-it-ok-to-use-a-global-variable-in-c). – Lundin Nov 13 '17 at 09:40
  • @Lundin Ok in that sense! Global variables, as goto's can be a nightmare if used inappropriately and in large quantity. But, as explained also in the answers you pointed out, could be the correct choice for some application. I wouldn't be such an integralist about them as I like, for my convenience, to break code in specialized modules even as subpart of a specific function (I.e. on an I/O section I create a module for input functions and another for output). But anyway the comment was about how to do what the OP asked, But I forget to warn about the (**ab**)use that can derive. – Frankie_C Nov 13 '17 at 11:24

1 Answers1

0

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.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    is not scope of struct reg xyz_reg inside the main() function? but i want it to be global – Gaurav Kumar Nov 11 '17 at 08:47
  • @GauravKumar Why? There is never a reason to. Even if you are writing some hardware register map, you shouldn't be using global variables. Nor should you use bit-fields, because they are completely unreliable. – Lundin Nov 13 '17 at 07:47