C++ #defining enum states - c++

I am wondering if I made a good decision when I defined all states of my enum to their shorter counterparts: just to tidy up the code.Code:Enum:
enum class ESelectedCharacterState : uint8
{
SS_WantsWalk,
SS_WantsJog,
SS_WantsCrouch,
SS_WantsProne,
SS_WantsJump
};
Defining:
#define WantsWalk ESelectedCharacterState::SS_WantsWalk
#define WantsJog ESelectedCharacterState::SS_WantsJog
#define WantsCrouch ESelectedCharacterState::SS_WantsCrouch
#define WantsProne ESelectedCharacterState::SS_WantsProne
#define WantsJump ESelectedCharacterState::SS_WantsJump
Case with no #defined enum states:
switch (StateSelected)
{
case ESelectedCharacterState::SS_WantsWalk:
break;
case ESelectedCharacterState::SS_WantsJog:
break;
case ESelectedCharacterState::SS_WantsCrouch:
break;
case ESelectedCharacterState::SS_WantsProne:
break;
case ESelectedCharacterState::SS_WantsJump:
break;
default:
break;
}
Case with #defined enum states:
switch (StateSelected)
{
case WantsWalk:
break;
case WantsJog:
break;
case WantsCrouch:
break;
case WantsProne:
break;
case WantsJump:
break;
default:
break;
}
This is actually a small bit of code but I use this enum very frequently in my project.

Using a typedef would be a cleaner way to achieve this, by making your enum's type shorter.
typedef ESelectedCharacterState ESCS;

Related

how to only indent brackets after case labels using clang-format

I wanna a style that only indent brackets after case labels, while keeping case label not indented.
this is what I want:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
I find an option IndentCaseLabels, but it will the whole things include the case label, neither true or false isn't what I want
true:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
false:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
Is this style possible in clang-format? If is, how could I Configure it?
It's just immediate above one you found in the manual.
IndentCaseBlocks: true
Indent case label blocks one level from the case label.
false: true:
switch (fool) { vs. switch (fool) {
case 1: { case 1:
bar(); {
} break; bar();
default: { }
plop(); break;
} default:
} {
plop();
}

Why does my switch/case default when using enums?

I have the following switch/case statement in Arduino 1.8.7 where the variable led is an integer:
switch (led) {
case ALL: {
/* do stuff */
break;
}
case LED1: {
/* do stuff */
break;
}
case LED2: {
/* do stuff */
break;
}
case LED3: {
/* do stuff */
break;
}
case LED4: {
/* do stuff */
break;
}
default: {
break;
}
}
I also have the following enum:
enum LED_References_e
{
ALL = 0,
LED1 = 1,
LED2 = 2,
LED3 = 3,
LED4 = 4
};
When using the enumerated values as cases to the statement, the statement always hits the default clause. If I substitute the enumerated values for the integers that they represent (i.e.case 0: ... case 1: ...) then the statement functions as expected.
I have tried, when using the enumerated values within the statement, to reference the enumerator as the value that the switch is performed on:
switch ((LED_References_e)led)
But this also defaults every time.
I am using another enumerator within my program and this functions correctly, however it is conditionally tested using if/else as opposed to switch/case.
My question is twofold:
Why does the switch/case statement seemingly not work with enumerated values?
What fundamental difference am I missing between if/else and switch/case?
Assuming Max Langhof is correct and there are other names ALL, LED1, etc... in scope at the switch so that the LED_References_e ones are shadowed, this should help:
I'm not 100% certain about the differences between standard C++ and Arduino C++, but you should be able to do the following:
enum LED_References_e
{
ALL = 0,
LED1 = 1,
LED2 = 2,
LED3 = 3,
LED4 = 4
};
switch (led) {
case LED_References_e::ALL: {
/* do stuff */
break;
}
case LED_References_e::LED1: {
/* do stuff */
break;
}
case LED_References_e::LED2: {
/* do stuff */
break;
}
case LED_References_e::LED3: {
/* do stuff */
break;
}
case LED_References_e::LED4: {
/* do stuff */
break;
}
default: {
break;
}
}
What this does is it tells the compiler you explicitly want LED1...LED4 from the LED_References_e enum.
If there are other LEDxes in the same scope, this should disambiguate.

C++ Forced to do a weird cast to get rid of "expression should be a modifiable lvalue" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I just faced a strange enum assignation problem and I thought you could have helped me out. I have an enum like this:
enum LIB_EDXENGINE CameraFeatureDataType
{
CFDT_ENUMERATION,
CFDT_64BITS_UINT,
CFDT_64BITS_INT,
CFDT_64BITS_FLOAT,
CFDT_BOOLEAN,
CFDT_32BITS_UINT,
CFDT_32BITS_INT,
CFDT_32BITS_FLOAT,
};
And I have a class with an instance of this enum.
EDITED:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return m_eCameraFeatureDataType;
}
The only solution that I found to get rid of the error is to cast the member variable to its own type, which is weird I think.
EDITED TOO:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
(CameraFeatureDataType)m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return m_eCameraFeatureDataType;
}
You declared method as const and then you do member attribute modification:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
this->m_eCameraFeatureDataType = CFDT_BOOLEAN;
break;
case NT_Integer:
this->m_eCameraFeatureDataType = CFDT_64BITS_INT;
break;
case NT_Float:
this->m_eCameraFeatureDataType = CFDT_64BITS_FLOAT;
break;
case NT_Enumeration:
this->m_eCameraFeatureDataType = CFDT_ENUMERATION;
break;
}
return this->m_eCameraFeatureDataType;
}
You propably should write:
const CameraFeatureDataType & LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
return CFDT_BOOLEAN;
case NT_Integer:
return CFDT_64BITS_INT;
case NT_Float:
return CFDT_64BITS_FLOAT;
case NT_Enumeration:
return CFDT_ENUMERATION;
}
return CFDT_UNKNOWN;//change to default value
}
Your problem is that you are trying to modify a member variable in a const method.
This is what your method would look like normally:
CameraFeatureDataType LibEDX::CVBGenicamFeature2::GetFeatureType() const
{
switch (m_eNodeType)
{
case NT_Boolean:
return CFDT_BOOLEAN;
case NT_Integer:
return CFDT_64BITS_INT;
case NT_Float:
return CFDT_64BITS_FLOAT;
case NT_Enumeration:
return CFDT_ENUMERATION;
default:
// don't know either, you decide...
}
}
I have no idea why you even have a member variable, or why you would return an enum value as a const reference. If you need one of those, you should think hard about why you need them. The keyword for changing a member variable in a constmethod is mutable.

Cast const int pointer to int, in a switch case node

In my STM32 code i have an
#define USART1 ((USART_TypeDef *) USART1_BASE)
and i would like to have
switch((uint32_t)ptr)
{
case USART1: return 1;
(...)
But gcc-arm (6.3.1) give me an error
error: reinterpret_cast from integer to pointer
I found an information that i can use
case __builtin_constant_p(USART1): return 0;
but this is only gcc solution? Is there something more generic?
There is UART1_BASE which is just the sum of a couple of unsigned integer constants. See the machine header:
#define PERIPH_BASE 0x40000000U
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000U)
#define USART1_BASE (APB2PERIPH_BASE + 0x1000U)
So should be able to use
switch((unsigned int)ptr) {
case USART1_BASE: return 1;
}
You forgot to cast pointer to integer in the case statement as well.
Example from my working code:
switch ((uint32_t)gpio) {
case (uint32_t)GPIOA:
EXTI_cfgr = 0b0000;
break;
case (uint32_t)GPIOB:
EXTI_cfgr = 0b0001;
break;
case (uint32_t)GPIOC:
EXTI_cfgr = 0b0010;
break;
default:
break;
}
USART1_BASE is a number in the header files of the STM32 development environment. You can compile your code when you decided what type shall be used in the switch. I recommend uint32_t:
switch((uint32_t)ptr)
{
case USART1_BASE: return 1;
(...)
If you like more readability you can try to remove the cast from the switch:
uint32_t ptr_value = (uint32_t)ptr;
switch(ptr_value)
{
case USART1_BASE: return 1;
(...)

Switch statement doesn't work with enum (C++)

enum Maximum_Value{
MAXIMUM_VALUE_1 = 0,
MAXIMUM_VALUE_7 = 1,
MAXIMUM_VALUE_15 = 2,
MAXIMUM_VALUE_26 = 3,
MAXIMUM_VALUE_34 = 4
};
int value_from_function = functionetc();
switch(value_from_function){
MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);
}
The code above always seems to hit the default statement, printing "default :0" even though that should hit MAXIMUM_VALUE_1.
I've tried casting the variable in switch to no effect
I guess I should save the return value into a variable of type "Maximum_Value", but why doesn't the code work anyway?
Edit: Thanks for pointing out the awfully stupid mistake everyone :P. The root of the problem was copying coding from systemverilog, which uses 'case' as a keyword instead of 'switch', and doesn't require 'case' at the start of each case
Enumerators aren't labels but switch statements jump to labels. You use case to create a label switch statements can jump to:
case MAXIMUM_VALUE_1: ...; break;
Add case keyword then it will work.
case MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
case MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
case MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);
you are missing the case keyword before every label!
syntax of switch case is-
switch(type){
case type1: ....; break;
case type2: ....; break;
......
default: .....;
}