MrXxxnamelessxxx
MrXxxnamelessxxx

Reputation: 31

typedef enum: Different values for one member

I'm wondering if I can assign different values to the same member of an typedef enum like this...:

typedef enum {

    START   = 0x01,
    DATA    = 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    CRC     = 0x0A, 0x0B

}bytes_t;

...so I can later use it like this:

bytesReceived++;                        // incremented for every received byte

switch (bytesReceived) {

    case START:
        dPkg->startByte = dpkgRxBuffer[bytesReceived];              
        break;

    case DATA:
        dPkg->data = dpkgRxBuffer[bytesReceived];
        break;

    case CRC:
        dPkg->crc = dpkgRxBuffer[bytesReceived];
        break;

}

So the program carries out the DATA case eight times if called in a loop. Does this work? It's only a first idea, so I can't give you further context unfortunately.

Upvotes: 2

Views: 1043

Answers (5)

dbush
dbush

Reputation: 225767

Each name in an enum must have a single value. A symbol can't represent multiple values at once.

typedef enum {
    START   = 0x01,
    DATA2   = 0x02,
    DATA3   = 0x03,
    DATA4   = 0x04,
    DATA5   = 0x05,
    DATA6   = 0x06,
    DATA7   = 0x07,
    DATA8   = 0x08,
    DATA9   = 0x09,
    CRCA    = 0x0A,
    CRCB    = 0x0B,
}bytes_t;

What you can do in your switch statement is take advantage of case fallthrough to have multiple cases do the same thing:

switch (bytesReceived) {

    case START:
        dPkg->startByte = dpkgRxBuffer[bytesReceived];              
        break;

    case DATA2:
    case DATA3:
    case DATA4:
    case DATA5:
    case DATA6:
    case DATA7:
    case DATA8:
    case DATA9:
        dPkg->data = dpkgRxBuffer[bytesReceived];
        break;

    case CRCA:
    case CRCB:
        dPkg->crc = dpkgRxBuffer[bytesReceived];
        break;

}

Upvotes: 0

Jacajack
Jacajack

Reputation: 779

Each enum name can have only one value. Here are some alternatives you can use.

As imans77 pointed out in comments, you can use if statements instead of switch

if ( bytesReceived == 0x01 ) handle_start( );
else if ( bytesReceived < 0x0a ) handle_data( );
else handle_crc( );

Or if you really want to keep the enum and the switch, you can do it as everyone else here pointed out:

enum
{
   START = 0x01,
   DATA0 = 0x02,
   DATA1 = 0x03,
   ...
   DATA7 = 0x09,
   CRC1 = 0x0a,
   CRC2 = 0x0b
} byte_t;

switch ( bytesReceived )
{
   case START: handle start( ); break;

   case DATA0:
   case DATA1:
   case DATA2:
   ...
   case DATA7:
        handle_data( );
        break;

   case CRC1:
   case CRC2:
        handle_crc( );
        break;
}

I hope this helps.

Upvotes: 0

ritlew
ritlew

Reputation: 1682

enum is probably not what you want here. I would so something like this:

#define START   0x01
#define DATA    0x02
#define CRC     0x0A
#define INVALID 0x0C

if (bytesReceived >= INVALID){
    // throw error
} else if (bytesReceived >= CRC){
    dPkg->crc = dpkgRxBuffer[bytesReceived];
} else if (bytesReceived >= DATA){
    dPkg->data = dpkgRxBuffer[bytesReceived];
} else if (bytesReceived >= START){
    dPkg->startByte = dpkgRxBuffer[bytesReceived];
} 

This way you can edit the ranges without having to change a large amount of switch statements every time. There are even more systematic ways to do this, but for a simple application such as what you presented, this would suffice.

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 142005

That's not possible. Enum is a constant with a distinct value.
Use multiple cases:

typedef enum {
    START   = 0x01,
    DATA_2  = 0x02, 
    DATA_3  = 0x03,
    DATA_4  = 0x04,
    ...
    DATA_9  = 0x09,
    CRC_1   = 0x0A, 
    CRC_2   = 0x0B
}bytes_t;

switch (variable) {
    case START:
        dPkg->startByte = dpkgRxBuffer[bytesReceived];              
        break;
    case DATA_2:
    case DATA_3:
    ...
    case DATA_9:
        dPkg->data = dpkgRxBuffer[bytesReceived];
        break;
    case CRC_1:
    case CRC_2:
        dPkg->crc = dpkgRxBuffer[bytesReceived];
        break;
}

or use if with a range:

typedef enum {
    START   = 0x01,
    DATA_START  = 0x02, 
    DATA_STOP   = 0x09,
    CRC_1     = 0x0A, 
    CRC_2     = 0x0B
}bytes_t;

if (variable == START) {
        dPkg->startByte = dpkgRxBuffer[bytesReceived];
} else if (DATA_START <= variable && variable <= DATA_STOP) {
        dPkg->data = dpkgRxBuffer[bytesReceived];
} else if (variable == CRC_1 || variable == CRC_2) {
        dPkg->crc = dpkgRxBuffer[bytesReceived];
}

Upvotes: 3

yadhu
yadhu

Reputation: 1333

As mentioned by @Jacajack, You can't assign multiple values to one enum member variable, However you can achieve the same thing by using a switch logic. with multiple values for byteReceived result in same logic get executed. I hope follwing snippet will be useful.

switch (bytesReceived) {

    case START:
        dPkg->startByte = dpkgRxBuffer[bytesReceived];              
        break;

    case 0x02: //List all the cases, for which same action needs to be executed.
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x06:
        dPkg->data = dpkgRxBuffer[bytesReceived];
        break;

    case CRC:
        dPkg->crc = dpkgRxBuffer[bytesReceived];
        break;

}

Upvotes: 2

Related Questions