Reputation: 329
I have a simple C code example using a struct
in a struct
.
HermannS
.age
with \ref ottoS::HermannS::age
.\ref ottoS.name.age
etcHermannS
have to be the same.Problem: But now the code create an redefinition-error
struct ottoS {
struct HermannS {
int age;
} name;
};
struct otherS {
struct HermannS {
int size;
} name;
};
int main ()
{
return 0;
}
I get the following error-message:
main.c:16:10: error: redefinition of ‘struct HermannS’
struct HermannS {
^~~~~~~~
main.c:10:10: note: originally defined here
struct HermannS {
^~~~~~~~
Question: how to define a struct
in a struct
and reuse the name HermannS
?
better Question: is there a gcc extension (prefix) to hide this error? → but this would be a very high price to pay for a simple doxygen documentation issue.
Upvotes: 0
Views: 1271
Reputation: 14107
As the program is ill-formed it will not compile. However if struct HermannS
is never used except the declaration then you could use the following trick.
If HermannS
is removed then ottoS.name
and otherS.name
would become anonymous structs and the code would compile. All anonymous structs are independent types. Just pass -DHermannS=
to the GCC's command.
gcc prog.c -DHermannS=
It will add a macro HermannS
that expands to an empty token.
Do not pass this option to doxygen to let it generate a proper documentation.
Upvotes: 1
Reputation: 14107
C standard say in section 6.7.2.1 para 8
The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit.
So all structs within the same translation unit share the same namespace.
HermannS
is redefined thus code is ill-formed.
Some workaround would be adding a prefix with the parent structure name:
struct ottoS {
struct ottoS_HermannS {
int age;
} name;
};
struct otherS {
struct otherS_HermannS {
int size;
} name;
};
Latest C standards allow the implementation to accept characters from the extended set like $
. It will help avoid collisions with more conventional names. It works with gcc. However, the code will no longer be portable.
struct ottoS {
struct ottoS$HermannS {
int age;
} name;
};
struct otherS {
struct otherS$HermannS {
int size;
} name;
};
It mimics ::
operator form C++ a bit. You could use some other unicode character and use it to postprocess your Doxygen documentation with sed-like tool. I mean replacing magic character with ::
.
Upvotes: 1
Reputation: 69306
You can't, as the compiler is telling you, and you really do not need to either. If you're not using that structure anywhere else, just don't name it:
struct ottoS {
struct {
int age;
} name;
};
struct otherS {
struct {
int size;
} name;
};
The only other (obvious) solution is to name the two inner structs differently.
If your logic/code/documentation is based on the fact that you need those two different structures to have the same name, then I would advise revisiting the logic, because it looks flawed.
is there a gcc extension (prefix) to hide this error?
No there is not. This is not a simple error, it's invalid C code: you are effectively defining two different types under the same name. The compiler will not be able to compile your code unless you avoid this.
Upvotes: 1
Reputation: 123458
A struct
declaration does not create a new namespace in C the way it does in C++, so you can't create type names that are "local" to a struct
type. The tag name HermannS
can only be used for one struct
type definition.
C has four name spaces:
:
or goto
);struct
, union
, or enum
).
or ->
)Unfortunately, what you're trying to do won't work in C - you'll have to use a different tag name for each inner struct definition.
Upvotes: 3