Reputation: 347
Saw a lot of similar questions but none answer my question here:
Suppose I have an enum Property
:
enum
{
PROP_A = 1,
PROP_B,
N_PROPERTIES
} Property;
When I try to use it in a switch statement like this:
// file test.c
enum
{
PROP_A = 1,
PROP_B,
N_PROPERTIES
} Property;
int main(void)
{
int a = 0;
switch ((Property) a)
{
case PROP_A:
break;
case PROP_B:
break;
default:
break;
};
return 0;
}
The compiler throws this error:
test.c: In function ‘main’:
test.c:11:20: error: expected ‘)’ before ‘a’
11 | switch ((Property) a)
| ~ ^~
| )
What is wrong with this code? For reference, in the GObject documentation they have this snippet:
typedef enum
{
PROP_FILENAME = 1,
PROP_ZOOM_LEVEL,
N_PROPERTIES
} ViewerFileProperty;
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static void
viewer_file_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ViewerFile *self = VIEWER_FILE (object);
switch ((ViewerFileProperty) property_id)
{
case PROP_FILENAME:
g_free (self->filename);
self->filename = g_value_dup_string (value);
g_print ("filename: %s\n", self->filename);
break;
case PROP_ZOOM_LEVEL:
self->zoom_level = g_value_get_uint (value);
g_print ("zoom level: %u\n", self->zoom_level);
break;
default:
/* We don't have any other property... */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
Which is essentially the same thing. Therefore it must be possible. What's wrong with my version?
Upvotes: 2
Views: 929
Reputation: 311010
In this declaration
enum
{
PROP_A = 1,
PROP_B,
N_PROPERTIES
} Property;
you declared an object Property
of an unnamed enumeration type.
So in the switch statement
switch ((Property) a)
you are using a syntactically incorrect expressions with two objects Property
and a
.
It seems you mean
typedef enum
{
PROP_A = 1,
PROP_B,
N_PROPERTIES
} Property;
Pay attention that you may just write
switch ( a )
In C enumerators have the type int
. That is these enumerators PROP_A, PROP_B, N_PROPERTIES all have the type int
. So the casting that you tried to apply (if the enumeration would be declared correctly) is redundant.
Upvotes: 3
Reputation: 180306
Suppose I have an enum Property:
enum { PROP_A = 1, PROP_B, N_PROPERTIES } Property;
Your code does not define Property
as an enum type. It declares it as a variable whose type is an untagged enum type. Typecast operators must be constructed from types, not variables, so (Property) a
is invalid.
That cast is also unnecessary. One way to solve the problem would be simply to drop it:
switch (a) {
case PROP_A:
break;
case PROP_B:
break;
default:
break;
}
Alternatively, if you mean to define Property
as a type alias, then that is the function of typedef
:
typedef enum {
PROP_A = 1,
PROP_B,
N_PROPERTIES
} Property;
Personally, however, I am not a fan of typedef
. It has a few good uses, but it tends to be applied far beyond those. If I wanted to declare an enum type that I could reference apart from its declaration, then I would include a tag:
enum property {
PROP_A = 1,
PROP_B,
N_PROPERTIES
};
int main(void) {
int a = 0;
switch ((enum property) a) {
case PROP_A:
break;
case PROP_B:
break;
default:
break;
}
return 0;
}
(The cast is included for demonstrative purposes -- it's still unnecessary.)
Upvotes: 3
Reputation: 1980
You need to add typedef
before enum
to identify Property
as a type. In the other example you provided for comparison, typedef
is used.
Upvotes: 1