Scope and Structure Types
There are two problems in the code shown.
The first is because C has some odd rules about structure definitions. One rule, in C 2018 6.7.2.3 4, is that structure declarations with the same tag (the name after struct
) declare the same type (a structure type with that name) only if they have the same scope:
All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type.…
When you declare a structure inside a function declaration, like this:
void foo(struct X *p);
Then the scope of X
is function prototype scope. Per 6.2.1 4, this scope ends at the end of the function declaration. Then, when you later define the structure, as with:
struct X { int q; }
it is in a different scope, and, per the rule above, the struct X
in the function declaration is not the same type as the struct X
in the later definition. One way to fix this is to move the structure definition prior to the function declaration. It also suffices merely to declare the structure tag prior to the function declaration, as with:
struct X;
void foo(struct X *p);
To fully understand what is happening here, we should consider two other issues. One issue is that we could have struct X
in two different translation units (different source files compiled separately), and calling a function defined with a struct X *
parameter in one unit from another unit that defines struct X
is allowed. This is because that, although the two struct X
types in the two translations units are different, they are compatible. 6.2.7 1 says:
… Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if…
Oddly, this rule only applies to structures declared in separate translation units. If we defined void foo(struct X *p { … }
prior to defining struct X
in one translation unit, they are different and incompatible types, but, if we define them in separate units, they are compatible types!
The second issue is how can this code work when the structure declarations have separate scopes:
struct X;
void foo(struct X *p);
The first struct X
has file scope (per 6.2.1 4), and the second struct X
has function prototype scope. The rule in 6.7.2.3 4 only applies if the declarations have the same scope, so it does not say these declare the same struct X
. Instead, there is another rule, in 6.7.2.3 9:
If a type specifier of the form struct-or-union identifier or enum
identifier occurs other than as part of one of the above forms, and a declaration of the identifier as a tag is visible, then it specifies the same type as that other declaration, and does not redeclare the tag.
(The “above forms” are definitions or stand-alone declarations.) This causes the struct X
in the function declaration after a prior file-scope struct X
to specify the same type.
Error in Argument
The second error is in the second argument passed to the function in this statement:
Fault_Bits_To_Flags( Master_Fault_Byte, *Fault_Flag);
Fault_Flag
is an array, so *Fault_Flag
is the first element of the array. This is a structure, not a pointer. To pass a pointer to the first element of the array, use:
Fault_Bits_To_Flags( Master_Fault_Byte, Fault_Flag);