简体   繁体   中英

C switch statement and enum explicit cast

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?

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.)

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.

You need to add typedef before enum to identify Property as a type. In the other example you provided for comparison, typedef is used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM