Flags, enum (C) - c

I'm not very used to programming with flags, but I think I just found a situation where they'd be useful:
I've got a couple of objects that register themselves as listeners to certain events. What events they register for is dependent on a variable that is sent to them when they are constructed. I think a nice way to do this would be to send bitwise OR connected variables, like such: TAKES_DAMAGE | GRABBABLE | LIQUID, etc. Then, in the constructor, the object can check what flags are set and register it self as listener for the ones that are.
But this is where I get confused. Preferably, the flags would be in an enum. But that is also a problem. If we have got these flags:
enum
{
TAKES_DAMAGE,/* (0) */
GRABBABLE, /* (1) */
LIQUID, /* (2) */
SOME_OTHER /* (3) */
};
Then sending the flag SOME_OTHER (3) will be the same as sending GRABBABLE | LIQUID, will it not?
How exactly do you deal with this stuff?

Your enumeration needs to be powers of two :
enum
{
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4,
SOME_OTHER = 8
};
Or in a more readable fashion :
enum
{
TAKES_DAMAGE = 1 << 0,
GRABBABLE = 1 << 1,
LIQUID = 1 << 2,
SOME_OTHER = 1 << 3
};
Why ? Because you want to be able to combine flags with no overlapping, and also be able to do this:
if(myVar & GRABBABLE)
{
// grabbable code
}
... Which works if the enumeration values look like this :
TAKES_DAMAGE: 00000001
GRABBABLE: 00000010
LIQUID: 00000100
SOME_OTHER: 00001000
So, say you've set myVar to GRABBABLE | TAKES_DAMAGE, here's how it works when you need to check for the GRABBABLE flag:
myVar: 00000011
GRABBABLE: 00000010 [AND]
-------------------
00000010 // non-zero => converts to true
If you'd set myVar to LIQUID | SOME_OTHER, the operation would have resulted in :
myVar: 00001100
GRABBABLE: 00000010 [AND]
-------------------
00000000 // zero => converts to false

another way of storing flags is to not bother with the underlying type at all. when using an enum, the enum values are stored by default into an unsigned int, which is 32 bits on a common computer. this gives you with only 32 possible flags: while certainly much, there are some cases where it is not sufficient.
now you can define your flag set this way:
typedef struct
{
int takes_damage : 1;
int grabbable : 1;
int liquid : 1;
int some_other : 1;
} flags;
if you never encountered this, the ': 1' part tells the compiler to only use 1 bit to store this struct member.
now you can define a variable to hold the flags, and work with those flags:
flags myflags = {1,0,0,1}; // defines a variable holding a set of flags, with an initial value of takes_damage & some_other
myflags.liquid = 1; // change the flags to include the liquid
if ( myflags.takes_damage ) // test for one flag
apply_damage();
if ( myflags.liquid && myflags.some_other ) // test for multiple flags
show_strange_behavior();
this method allows you to define any number of flags, without limitation, and you can extend your flag set at any time without fearing an overflow. the drawback is that testing a subset of the flags is more cumbersome and necessitate more code.

Yes. Instead, make your enum members powers of 2:
enum
{
TAKES_DAMAGE = (1 << 0),
GRABBABLE = (1 << 1),
LIQUID = (1 << 2),
SOME_OTHER = (1 << 3)
};

You should make the flags only powers of two, i.e. each is a bit in whatever data type you're storing this in, and nothing overlaps when you bitwise OR.

Can't you just set the values in the enum?
enum {
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4
}
Afterwards, just perfom bit-wise OR on them.

you need
enum
{
TAKES_DAMAGE = 1,
GRABBABLE = 2,
LIQUID = 4,
SOME_OTHER = 8
};

Related

One hot encoding of the states of a C FSM

Basically, I just would like to know if this is a good idea to manually one hot encode the states of a C FSM.
I implemented that to write an easy state transition validator:
typedef enum
{
FSM_State1 = (1 << 0),
FSM_State2 = (1 << 1),
FSM_State3 = (1 << 2),
FSM_StateError = (1 << 3)
} states_t;
Then the validation:
states_t nextState, requestedState;
uint32_t validDestStates = 0;
// Compute requested state
requestedState = FSM_State1;
// Define valid transitions
validDestStates |= FSM_State2;
validDestStates |= FSM_State3;
// Check transition
if (validDestStates & requestedState)
{
// Valid transition
nextState = requestedState;
}
else
{
// Illegal transition
nextState = FSM_StateError;
}
I know that I am limited to the maximum size of integer that I can use. But I don't have that many states. So it is not an issue
Is there something better than this encoding?
Are there some drawbacks I don't see yet?
Thanks for your help!
Edit: changed validation test according to user3386109 comment
Final thoughts
So final here is what I did:
1/ State enum is a "classical" enum:
typedef enum
{
FSM_State1,
FSM_State2,
FSM_State3,
FSM_StateError
} states_t;
2/ Bit fields for valid transitions:
struct s_fsm_stateValidation
{
bool State1IsValid: 1;
bool State2Valid: 1;
bool State3IsValid: 1;
bool StateErrorIsValid: 1;
/// Reserved space for 32bit reserved in the union
uint32_t reserved: 28;
};
3/ Create an union for the validation
typedef union FSM_stateValidation_u
{
/// The bit field of critical system errors
struct s_fsm_stateValidation state;
/// Access the bit field as a whole
uint32_t all;
} u_FSM_stateValidation;
4/ I changed the validation:
u_FSM_stateValidation validDestStates;
// Set valid states
validDestStates.state.State1 = true;
// Compute requestedState
requestedState = FSM_State2;
if ((validDestStates.all & ((uint32_t) (1 << requestedState)) ))
{
// Next state is legal
return requestedState;
}
else
{
return FSM_StateError;
}
From a quick Google, "one hot encoded" means that every valid code has precisely one bit set, which seems to be what you're doing. The search results suggested this was a hardware design pattern.
Drawbacks I can think of are...
As you suggest, you're dramatically limiting the number of valid codes - for 32 bits you have a maximum of 32 codes/states instead of more than 4 billion.
It's not ideal for lookup tables, which are a common implementation for switch statements. There are usually an intrinsic available to determine which is the lowest bit set, but I wouldn't bet on compilers using that automatically.
Those aren't big issues, though, provided the number of states is small.
The question IMO, then, is whether there's an advantage to justify that cost. It doesn't need to be a huge advantage, but there has to be some kind of point.
The best I can come up with is that you can use bitwise tricks to specify sets of states, so you can test whether the current state is in a given set efficiently - if you have some action that needs to be done in states (1<<0) and (1<<3), for example, you could test if (state & 0x9).

Store zeros from ints and use them later

I have 3 sensors that each provide either 0 or 1 (repeatedly in a loop). They are stored individually as int variables. These are then printed using the following:
print ("%d%d%d", Sensor1, Sensor2, Sensor3);
I want to store each combination (ex: 010, 001, 110, etc.) temporarily so that I can use it do something else (I want to have a switch or something eventually where I can do a different operation depending on the value of the sensor combination). I can't store it as an int since that drops the 0s in front.
How can I store these combinations?
You can use structure bit field for this.
struct Bit{
bool Sensor1 : 1;
bool Sensor2 : 1;
bool Sensor3 : 1;
};
int main(void)
{
struct Bit bit = {0, 1, 0};
printf ("%d%d%d", bit.Sensor1, bit.Sensor2, bit.Sensor3);
}
So you have
int Sensor1, Sensor2, Sensor3;
// have code to initialize above variables to 0 or 1
To store these as one integer in base 10, assuming they really all are 0 or 1, you can do:
int Sensors_10 = Sensor1 * 100 + Sensor2 * 10 + Sensor3;
And then to get them back:
Sensor1 = Sensors_10 / 100 % 10;
Sensor2 = Sensors_10 / 10 % 10;
Sensor3 = Sensors_10 % 10;
Obviously order of sensors can be whatever, as long as it matches between packing and unpacking.
But, you only need 1 bit to store each sensor, so could use binary:
int Sensors_2 = Sensor1 * 4 + Sensor2 * 2 + Sensor3;
...
Sensor1 = Sensors_2 / 4 % 2;
Sensor2 = Sensors_2 / 4 % 2;
Sensor3 = Sensors_2 % 2;
But, with computer binary numbers are special, so the binary version is more commonly written like this:
int Sensors_2 = Sensor1 << 2 | Sensor2 << 1 | Sensor3;
...
Sensor1 = Sensors_2 >> 2 & 1;
Sensor2 = Sensors_2 >> 1 & 1;
Sensor3 = Sensors_2 & 1;
Where |, <<, >> and & are bitwise OR, shift and AND operators, and explaining what they do is beyond scope of this question, but one note about them: When there are no "overlapping" one-bits and numbers are positive, then result of | is same as result of +.
Answer of haccks covers how to make C compiler do this for you, without doing your own bit manipulation.
To print Sensors_10 with leading zeros, you can do printf("%03d", Sensors_10);. C standard library does not have a way to print binary numbers directly, so you need your own code to print the bits one-by-one, so you might as well printf("%d%d%d", Sensor1, Sensor2, Sensor3); then.
You can use a 2D int array to store the values and use it later.
E.g int sen_value[1000][3]; use it in the loop to store the values.
Example how you can use it in loop:
#include <stdio.h>
int main ()
{
int i;
int sen_value[10][3];
for(i=0;i<10;i++)
{
//Assigning the values
sen_value[i][0] = 0;
sen_value[i][1] = 0;
sen_value[i][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[i][0],sen_value[i][1],sen_value[i][2]);
}
return 0;
}
Or you can use it just once and then reset it after each operation, For example:
#include <stdio.h>
int main ()
{
int sen_value[1][3];
//Assigning the values
sen_value[0][0] = 0;
sen_value[0][1] = 0;
sen_value[0][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[0][0],sen_value[0][1],sen_value[0][2]);
return 0;
}
If you are using a linux environment then by using the command you can easily save the output that are displayed in your console.
Let here sensor.c be your source file Then,
$ gcc -o a sensor.c
$ ./a > senser.txt
Then you have a .txt file with all output stored in a txt file. And these can be again used as inputs in your other.c files like :
$ gcc -o other other.c
$ ./other < senser.txt
If you want to store those sensor1,sensor2,sensor3 internally and use internally then you can simply use the arrays or Structure like :
main(){
int Sensor[1][3];
Sensor[0][0] = 0;
Sensor[0][1] = 1;
Sensor[0][2] = 0;
print ("%d%d%d", Sensor[0][0], Sensor[0][1], Sensor[0][2]);
}
While the leading zeroes of an integer are not displayed when printed, that does not mean they are "dropped"; they are merely implicit - that is a matter of the format specifier used in teh output of the value rather than the zeros not being present. An int is always a fixed number of binary digits.
Consider:
uint32_t sensor_state = (sensor3 << 3) | (sensor2 << 1) | sensor1 ;
Note that uint32_t is a type alias for an unsigned integer 32 bits in length. It is defined by including the <stdint.h> header file. In this case a plain int would work, but when you are dealing with data at the bit level it is good to be explicit (and unsigned). Here of course a uint8_t would work too, and if your target is an 8 bit device, I suggest you use that.
Here sensor_state is a binary combination of the three sensor values and will have one of the following values:
Sensors sensor_state
3 2 1 binary decimal hexadecimal
---------------------------------------
0 0 0 0000 0 0x00
0 0 1 0001 1 0x01
0 1 0 0010 2 0x02
0 1 1 0011 3 0x03
1 0 0 0100 4 0x04
1 0 1 0101 5 0x05
1 1 0 0110 6 0x06
1 1 1 0111 7 0x07
So you can switch on any combination:
switch( sensor_state )
{
case 0x00 :
...
break ;
case 0x01 :
...
break ;
case 0x02 :
...
break ;
...
case 0x07 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You might usefully create an enumeration for each combination:
enum eSensorStates
{
NO_SENSOR = 0,
SENSOR1,
SENSOR2,
SENSOR12,
SENSOR3,
SENSOR13,
SENSOR23,
SENSOR123
}
Then you can write:
switch( sensor_state )
{
case NO_SENSOR :
...
break ;
case SENSOR1:
...
break ;
case SENSOR2:
...
break ;
...
case SENSOR123 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You may of course use enumeration names that make specific sense in your application - that reflect the meaning or action for each combination rather than the generic names I have chosen.

How to Interpret typedef enum property on MCOIMAPMessage

My question is mostly about how interpret a typedef enum, but here is the background:
I am using MailCore2, and I am trying to figure out how to read the flags off of an individual email object that I am fetching.
Each MCOIMAPMessage *email that I fetch has a property on it called 'flags.' Flags is of type MCOMessageFlag. When I look up the definition of MCOMessageFlag, I find that it is a typedef enum:
typedef enum {
MCOMessageFlagNone = 0,
/** Seen/Read flag.*/
MCOMessageFlagSeen = 1 << 0,
/** Replied/Answered flag.*/
MCOMessageFlagAnswered = 1 << 1,
/** Flagged/Starred flag.*/
MCOMessageFlagFlagged = 1 << 2,
/** Deleted flag.*/
MCOMessageFlagDeleted = 1 << 3,
/** Draft flag.*/
MCOMessageFlagDraft = 1 << 4,
/** $MDNSent flag.*/
MCOMessageFlagMDNSent = 1 << 5,
/** $Forwarded flag.*/
MCOMessageFlagForwarded = 1 << 6,
/** $SubmitPending flag.*/
MCOMessageFlagSubmitPending = 1 << 7,
/** $Submitted flag.*/
MCOMessageFlagSubmitted = 1 << 8,
} MCOMessageFlag;
Since I do not know how typedef enums really work - particularly this one with the '= 1 << 8' type components, I am a little lost about how to read the emails' flags property.
For example, I have an email message that has both an MCOMessageFlagSeen and an MCOMessageFlagFlagged on the server. I'd like to find out from the email.flags property whether or not the fetched email has one, both or neither of these flags (if possible). However, in the debugger when I print 'email.flags' for an email that has both of the above flags, I get back just the number 5. I don't see how that relates to the typedef enum definitions above.
Ultimately, I want to set a BOOL value based on whether or not the flag is present. In other words, I'd like to do something like:
BOOL wasSeen = email.flags == MCOMessageFlagSeen;
BOOL isFlagged = email.flags == MCOMessageFlagFlagged;
Of course this doesn't work, but this is the idea. Can anyone suggest how I might accomplish this and/or how to understand the typedef enum?
These flags are used as in a bitmask.
This allows to store multiple on/off flags in a single numeric type (let it be an unsigned char or an unsigned int). Basically if a flag is set then its corresponding bit is set too.
For example:
MCOMessageFlagMDNSent = 1 << 5
1<<5 means 1 shifted to the left by 5 bits, so in binary:
00000001 << 5 = 00100000
This works only if no flag overlaps with other flags, which is typically achieved by starting with 1 and shifting it to the left by a different amount for every flag.
Then to check if a flag is set you check if the corresponding bit is set, eg:
if (flags & MCOMessageFlagMDNSent)
result will be true if the bitwise AND result is different from zero, this can happen only if the corresponding bit is set.
You can set a flag easily with OR:
flags |= MCOMessageFlagMDNSent;
or reset it with AND:
flags &= ~MCOMessageFlagMDNSent;
The values of the enum represent the individual bits, so you need bitwise operations to check for flags:
BOOL wasSeen = ( email.flags & MCOMessageFlagSeen ); // check if a bit was set
BTW: You code seems to suggest this is C, not C++. Tagging a question is both is almost always wrong, I suggest you pick the language you are using and remove the other tag.

hunting for a particular pair of bits '10' or '01' in a character array

This may be a slightly theoretical question. I have a char array of bytes containing network packets. I want to check for the occurrence of a particular pair of bits ('01' or '10')every 66 bits. That is to say once I locate the first pair of bits I have to skip 66 bits and check the presence of same pair of bits again. I am trying to implement a program with masks and shifts and it is kind of getting complicated. I want to know if someone can suggest a better way to do the same thing.
The code I have written so far looks something like this. It is not complete though.
test_sync_bits(char *rec, int len)
{
uint8_t target_byte = 0;
int offset = 0;
int save_offset = 0;
uint8_t *pload = (uint8_t*)(rec + 24);
uint8_t seed_mask = 0xc0;
uint8_t seed_shift = 6;
uint8_t value = 0;
uint8_t found_sync = 0;
const uint8_t sync_bit_spacing = 66;
/*hunt for the first '10' or '01' combination.*/
target_byte = *(uint8_t*)(pload + offset);
/*Get all combinations of two bits from target byte.*/
while(seed_shift)
{
value = ((target_byte & seed_mask) >> seed_shift);
if((value == 0x01) || (value == 0x10))
{
save_offset = offset;
found_sync = 1;
break;
}
else
{
seed_mask = (seed_mask >> 2) ;
seed_shift-=2;
}
}
offset = offset + 8;
seed_shift = (seed_shift - 4) > 0 ? (seed_shift - 4) : (seed_shift + 8 - 4);
seed_mask = (seed_mask >> (6 - seed_shift));
}
Another idea I came up with was to use a structure defined below
typedef struct
{
int remainder_bits;
int extra_bits;
int extra_byte;
}remainder_bits_extra_bits_map_t;
static remainder_bits_extra_bits_map_t sync_bit_check [] =
{
{6, 4, 0},
{5, 5, 0},
{4, 6, 0},
{3, 7, 0},
{2, 8, 0},
{1, 1, 1},
{0, 2, 1},
};
Is my approach correct? Can anyone suggest any improvements for the same?
Lookup Table Idea
There are only 256 possible bytes. That is few enough that you can construct a lookup table of all the possible bit combinations that can happen in one byte.
The lookup table value could record the bit position of the pattern and it could also have special values that mark possible continuation start or continuation finish values.
Edit:
I decided that continuation values would be silly. Instead, to check for a pattern that overlaps a byte, shift the byte and OR in the bit from the other byte, or manually check the end bits at each byte. Maybe ((bytes[i] & 0x01) & (bytes[i+1] & 0x80)) == 0x80 and ((bytes[i] & 0x01) & (bytes[i+1] & 0x80)) == 0x01 would work for you.
You didn't say so I am also assuming that you are looking for the first match in any byte. If you are looking for every match, then checking for the end pattern at +66 bits, that's a different problem.
To create the lookup table, I would write a program to do it for me. It could be in your favorite script language or it could be in C. The program would write a file that looked something like:
/* each value is the bit position of a possible pattern OR'd with a pattern ID bit. */
/* 0 is no match */
#define P_01 0x00
#define P_10 0x10
const char byte_lookup[256] = {
/* 0: 0000_0000, 0000_0001, 0000_0010, 0000_0011 */
0, 2|P_01, 3|P_01, 3|P_01,
/* 4: 0000_0100, 0000_0101, 0000_0110, 0000_0111, */
4|P_01, 4|P_01, 4|P_01, 4|P_01,
/* 8: 0000_1000, 0000_1001, 0000_1010, 0000_1011, */
5|P_01, 5|P_01, 5|P_01, 5|P_01,
};
Tedious. That's why I would write a program to write it for me.
This is a variation of the classic de-blocking problem that often comes up when reading from a stream. That is, data comes in discrete units that don't match up to the unit size that you wish to scan. The challenges in this are 1) buffering (which doesn't affect you because you have access to the whole array) and 2) managing all of the state (as you found out). A good approach is to write a consumer function that acts something like fread() and fseek() which maintains its own state. It returns the requested data you're interested in, aligned properly to the buffers you give it.

What does this enum mean?

I saw this line of code today and had no idea what it does.
typedef enum {
SomeOptionKeys = 1 << 0 // ?
} SomeOption;
Some usage or example would be helpful. Thanks!
It looks like it defines an enumerated type that is supposed to contain a set of flags. You'd expect to see more of them defined, like this:
typedef enum {
FirstOption = 1 << 0,
SecondOption = 1 << 1,
ThirdOption = 1 << 2
} SomeOption;
Since they are defined as powers of two, each value corresponds to a single bit in an integer variable. Thus, you can use the bitwise operators to combine them and to test if they are set. This is a common pattern in C code.
You could write code like this that combines them:
SomeOption myOptions = FirstOption | ThirdOption;
And you could check which options are set like this:
if (myOptions & ThirdOption)
{
...
}
The value of SomeOptionKeys is one, this is a useful representation when working with flags:
typedef enum {
flag1 = 1 << 0, // binary 00000000000000000000000000000001
flag2 = 1 << 1, // binary 00000000000000000000000000000010
flag3 = 1 << 2, // binary 00000000000000000000000000000100
flag4 = 1 << 3, // binary 00000000000000000000000000001000
flag5 = 1 << 4, // binary 00000000000000000000000000010000
// ...
} SomeOption;
Whit way each flag has only one bit set, and they could be represented in a bitmap.
Edit:
Although, I have to say, that I might be missing something, but it seems redundent to me to use enums for that. Since you lose any advantage of enums in this configuration, you may as well use #define:
#define flag1 (1<<0)
#define flag2 (1<<1)
#define flag3 (1<<2)
#define flag4 (1<<3)
#define flag5 (1<<4)
It just sets the enum to the value 1. It is probably intended to indicate that the values are to be powers of 2. The next one would maybe be assigned 1 << 1, etc.
<< is the left shift operator. In general, this is used when you want your enums to mask a single bit. In this case, the shift doesn't actually do anything since it's 0, but you might see it pop up in more complex cases.
An example might look like:
typedef enum {
OptionKeyA = 1<<0,
OptionKeyB = 1<<1,
OptionKeyC = 1<<2,
} OptionKeys;
Then if you had some function that took an option key, you could use the enum as a bitmask to check if an option is set.
int ASet( OptionKeys x){
return (x & OptionKeyA);
}
Or if you had a flag bitmap and wanted to set one option:
myflags | OptionKeyB

Resources