1

What's the main goal when using : #ifdef _MAIN_ in the header file in c program.

This is an example:

#ifndef _INTDSPMNG_H_
#define _INTDSPMNG_H_

#include <pthread.h>

typedef struct dspList_t 
{
    char mesfct[CL_MESFCT+1]; 
    char processus[CL_NOMLOG+1]; 
    char requete_json[CL_MSJSON+1]; 
    char reponse_json[CL_MSJSON+1]; 
    int actif; 
}dspList_t;

/* Gestion des erreurs */
#define CV_DSPMNG_OK    0      
#define CV_DSPMNG_ERROR 1
#define DELAI_REVEIL_DSPMNG     
#ifdef _MAIN_
    dspList_t *gDspmngTab = NULL;
    int nb_config_dspmng = 0;  
    PARAM_COM_WEBSRV ParamCom;  
#else
    extern dspList_t *gDspmngTab;         
    extern int nb_config_dspmng;    
    extern PARAM_COM_WEBSRV ParamCom;   
#endif

#endif
Electrob
  • 49
  • 7
  • 2
    I would assume it's to either declare the variables or use them from some other source that's declaring them - for example if the code is compiled as a program or a library. – fredrik Mar 05 '21 at 10:21
  • Can you share which header is using this? – jordanvrtanoski Mar 05 '21 at 10:26
  • @jordanvrtanoski : I shared th header file. – Electrob Mar 05 '21 at 11:03
  • Can you share all source files that use this header? Is this code in a repository? Can you find the commit the introduced the code? Is the commit authored by someone? You can try connecting with the person that wrote the code and ask him. Or with the company that provided the code and ask them. – KamilCuk Mar 05 '21 at 11:03
  • @KamilCuk: Okay – Electrob Mar 05 '21 at 11:06

2 Answers2

4

Customary practice is to declare an object (or function) in a header file and define it in one source file. For example, given an object named foo defined as MyType foo = 0; in a file named bar.c, the header file bar.h would declare MyType foo;. Then each source file that needed foo would use #include "bar.h" to get its declaration.

The author of the code you are asking about apparently decided to put the definition and declaration together. Their header file intdspmng.h (presumed from the name of the include guard) can be included in source files and will declare identifiers normally. But, when they include it in main.c or whatever they have designated as their main file, they first define _MAIN_, perhaps with #define _MAIN_ or #define _MAIN_ 1. Then, when they include intdspmng.h, it defines the identifiers instead of just declaring them.

In other words, that person may have thought “I want to keep the declarations and definitions of these things together, because it is easier to edit them that way and to see the association between the definition and the declaration. So I will write code that I can put in the header file but that only defines the things in my main file.”

That might not be entirely unreasonable. However, they have made a mistake. One purpose the declarations serve is providing a check that they match the definitions. If in the source file where identifiers are defined we also include the header that declares them, then the compiler sees the declarations and the definitions together, and it will report warnings or errors if they conflict, as can happen when a typographical error is made or a type is changed in one place but not another.

This can be remedied by always including the declarations, while the definitions remain included only if requested by the definition of _MAIN_:

extern dspList_t *gDspmngTab;         
extern int nb_config_dspmng;    
extern PARAM_COM_WEBSRV ParamCom;
#ifdef _MAIN_
    dspList_t *gDspmngTab = NULL;
    int nb_config_dspmng = 0;  
    PARAM_COM_WEBSRV ParamCom;  
#endif

While that remedies this deficiency, I still would not say that I recommend this approach.

Another issue is that identifiers beginning with an underscore followed by an uppercase letter or another underscore are reserved, according to the C standard. They should be avoided in general program code, although compilers and “system” libraries may use them. So _MAIN_ should be changed to something else, such as DefineMainObjects.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
-2

It shows that the project has the wrong structure.

    extern dspList_t *gDspmngTab;  
    extern int nb_config_dspmng;     
    extern PARAM_COM_WEBSRV ParamCom;  

Those lines should be in the header file. Then all .c files using this objects should include it. Only one source file should define the actual objects.

IMO the author of the code needed declarations but never heard about header files. So he decided to do this #ifdef "black magic"

0___________
  • 60,014
  • 4
  • 34
  • 74
  • To complete what you are writing : only one file can define the variables and all others use external definitions. So to not have to write a specific c file for this, the author decided that the file defining the variables would be the file containing main as it is unique among a program. – Ptit Xav Mar 05 '21 at 11:15
  • @PtitXav: thank you , that's comprehensive. – Electrob Mar 05 '21 at 11:33