I found some code that made me a bit intrigued: there is a header file declaring only structures that are being used in code for an embedded system written in C.
This is an example of code in the header:
#ifdef _structures_h_
extern struct{
uint16_t State_ON;
uint16_t State_OFF;
uint16_t State_HI;
uint16_t Counter;
}Switch;
#endif
#ifndef _structures_h_
#define _structures_h_
struct{
uint16_t State_ON;
uint16_t State_OFF;
uint16_t State_HI;
uint16_t Counter;
}Switch;
#endif
In the source files that make use of those structures, in some of them, the inclusion is done like this:
#define _structures_h_
#include "structures.h"
In others there is just the inclusion of the header file as shown below:
#include "structures.h"
My doubt is, is there some reason for declaring the structures in both ways in the same header file?
Is there any difference or relevant impact in coding declaring the same struct as extern or not in a header filer?
This is the first time that I have found such a situation and I was not able to find a reasonable explanation for using this.
The difference between the two code sections is that, in the first (the one that has the
externkeyword), the structure variable is declared but not defined. That is, the code specifies that theSwitchvariable is defined elsewhere (in another translation unit). However, in the second section, theSwitchvariable is formally declared and defined – or, at least, tentatively defined; that tentative definition will become an actual definition if/when the compilation of the translation unit completes with no other full definition (i.e., one with an initializer) occurring.In that second conditional block, the definition of the
_structures_h_token is very strange; and, unless there is more to the header than you have shown, I can really see no purpose for it:Switchvariable with different types (even though those types have exactly equivalent definitions, they are still separate types); that redefinition is an error.Switchvariable from each of the TUs that include the header without first themselves defining the_structures_h_token.But I would agree with you and the other answerer that code like this is both confusing and error-prone: For example, using that header in multiple translation units without a preceding
_structures_h_definition will cause multiple definitions of theSwitchvariable.Also, rather than using the
#ifndef ...block, a simple#elsewould suffice and make things clearer (IMHO).Here's a shortened, annotated version of the header:
Or, an even shorter way, which avoids the multiple specifications of the structure (and the errors that could lead to), is to define a separate 'linkage' macro that is either
externor nothing: