问题
In the library FreeImagePlus, in FreeImage.h, there is a funny #define
which seems to create a typedef
and an enum
with the same name:
#define FI_ENUM(x) typedef int x; enum x
This is expanded by the preprocessor to code like:
typedef int FREE_IMAGE_FILTER;
enum FREE_IMAGE_FILTER {
FILTER_BOX = 0,
FILTER_BICUBIC = 1,
[...]
What does this do? Is it even legal to have a typedef
and an enum
with the same name?
And isn't an enum
compatible to int
anyway? Why does FreeImage do this?
回答1:
Names of structures, unions and enumerations lives in their own namespace. That's why you can declare a struct
/union
/enum
variable with the same name as the actual struct
/union
/enum
.
And it's not the name of the complete enum
(e.g. for enum X
I mean the X
) that has to be compatible with an integer, it's the names inside the enumeration.
回答2:
Quoting C99 N1256 draft 6.2.1 "Scopes of identifiers":
An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter.
which means that in:
typedef int id;
id
is an identifier.
And from 6.2.3 "Name spaces of identifiers":
BEGIN QUOTE
If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers, as follows:
- label names (disambiguated by the syntax of the label declaration and use);
- the tags of structures, unions, and enumerations (disambiguated by following any of the keywords struct, union, or enum);
- the members of structures or unions; each structure or union has a separate name space for its members (disambiguated by the type of the expression used to access the member via the . or -> operator);
- all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
END QUOTE
So in:
typedef int id;
enum id {ID0};
- the first
id
is an ordinary identifier - the second is a tag identifier
an both can coexist pacifically.
On the other hand, we could not do something like:
typedef int id;
int id;
because both would be ordinary identifiers.
来源:https://stackoverflow.com/questions/17918380/typedef-and-enum-with-same-name