Constant integral expression required error - c

I am writing code for AVR ATmega32-A microcontroller. I am using switch case as shown below.
unsigned char Command;
unsigned int Param;
void runCom(void){
switch(Command){
case(NO_COM):
Command = 0;
break;
case(INF):
printf("\r\n\r\n");
printf("university\r\n");
printf("sweden\r\n");
printf("Ver. 1.0A\r\n");
Command = 0;
break;
case (DB):
Command = 0;
break;
case(CLEARM):
Command = 0;
break;
default:
Command = 0;
break;
}
}
the above code is working but now i want to add one more case in that switch like as shown below.
unsigned char Command, Command1;
unsigned int Param;
void runCom(void){
switch(Command){
case(NO_COM):
Command = 0;
break;
case(INF):
printf("\r\n\r\n");
printf("university\r\n");
printf("sweden\r\n");
printf("Ver. 1.0A\r\n");
Command = 0;
break;
case (DB):
Command = 0;
break;
case(ADC):
printf("ADC Value",ReadAd());
printf("Enter Amplification stage");
switch(Command1){
case(stage1):
PORTC=0x00;
DDRC=0xC0;
printf("ADC Value",ReadAd());
Command1 = 0;
break;
case(stage2):
PORTC=0x00;
DDRC=0x03;
printf("ADC Value",ReadAd());
Command1 = 0;
break;
}
Command = 0;
break;
case(MEM):
Command = 0;
break;
case(CLEARM):
Command = 0;
break;
default:
Command = 0;
break;
}
}
I am getting error like
undefind symbol 'ADC'
undefind symbol 'stage1'
undefind symbol 'stage2'
then i have declared like this
unsigned char Command, ADC, Command1, stage1, stage2;
unsigned int Param;
now i am getting error like
constant integral expression required at line case(ADC)
constant integral expression required at line case(stage1)
constant integral expression required at line case(stage2)
so please can any one suggest me how to overcome this error. I haven't declared WGP, WGF, INF any where but I am not getting "undefined symbol of WGF, WGP, INF. why this error occurring for ADC only. i have fallowed same switch case rules as i used before. any suggestions appreciated.
Thanks in advance.

The values in a case needs to be constants or literals.
If you look up e.g. WGP you will see that it's most likely a #define'd literal. Do the same for your new values.

The values you use in the cases of a switch statement must be compile-time constants. That is, they must have fixed values that are known to to the compiler at compile time.
There are four main ways to do this.
You can use a constant literal (a number).
case 42:
Note that using unnamed values ("magic numbers") isn't recommended because it doesn't document the code in any way, and makes the code fragile (what if you need to change the value to 43 in five different places and forget one?)
You can use a preprocessor constant.
#define COMMAND_CODE 42
...
case COMMAND_CODE:
That's better because if you need to changet the command code value to 43 you only have to change the #define (which should only occur once, in a header file).
You can use an enum.
typedef enum { COMMAND_ON=42, COMMAND_OFF=2, COMMAND RESET=77 } command_codes:
...
case COMMAND_ON:
In C++, if your compiler is reasonably modern, you can use a constant:
const int magic_number = 42;
case magic_number:
(Note that the switch value shown in a case statement does NOT need to have parentheses around it.)
From the code you have shown, it seems that you have defined Command, ADC, etc., as variables (rather than as constants). In this case the compiler can't know what value those variables will have at execution time when it compiles the code. The language specifies that case values must be known at compile time so that the compiler can generate fast code (faster then a whole series of if ... else if ... else if statements).

Related

MISRA demand a single point of exit for a function for a "lookup table" function

Misra standard demand a single point of exit for a function, but I have the following "conversion" code
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
default:
break;
}
log_error("ERROR!!!!!");
assert(1==0);
}
Is this valid?
I need to convert it to a single return function?
And what is the best way of handling the default case?
this creates an unreachable code in theory (the error is to warn in case one add a value in the enum and not add a corresponding case)
This is an embedded system btw having those asserts create issues?
Thanks,
Nick
EDITED:
the default case should be never called if there are no errors (for example a programmer add another value in the enum and doesn't add a corresponding case
another options would be to remove the default at all but that violates another misra rule
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
}
//should never reach this line
assert(1==0);
}
This will generate a warning if I compile and don't specify all the cases in the enum (I think)
Very simply:
int my_conv_funct(my_enum_t value)
{
int result = -1;
switch(value)
{
case CASE_A:
result = 0;
break;
case CASE_B:
result = 1;
break;
case CASE_C:
result = 2;
break;
default:
break;
}
if(result == -1)
{
log_error("ERROR!!!!!");
assert(1==0);
}
return result;
}
Is this valid?
It does not comply with the MISRA rule you described.
I need to convert it to a single return function?
To comply with the MISRA rule, yes.
And what is the best way of handling the default case?
We cannot judge what is "best" for your particular circumstances and use.
This is an embedded system btw having those asserts create issues?
The idea of an assertion is that it helps you find programming errors during development, but (in principle) it gets disabled via build options in code that is intended to be used in production. If that model is followed then the assertion itself probably does not create an issue, but the fact that the function does not return a value in the default case (if assertions are disabled) does. If the program must terminate in the event that the default case is exercised then it should call abort(), or some other function having that effect. Otherwise, it should return a sensible value in the default case.
I would probably write the function more like this:
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
case CASE_B:
case CASE_C:
break;
default:
log_error("ERROR!!!!!");
assert(0);
break;
}
return value;
}
There is now just one exit point from the function, and if it returns at all then it returns its argument (implicitly converted to type int).
First of all please check this answer: Best practice for compute the function return value. The MISRA-C rule is advisory and I recommend to make a permanent deviation against it. Personally I replace it with a rule such as:
"Multiple return statements in a function should be avoided unless they make the code more readable/maintainable."
The rationale to avoid returning from multiple places inside nested, complex code is sound, but far less so in clean and readable functions.
In your specific case though, I would perhaps have rewritten the function like this (MISRA compliant without ignoring the rule):
uint32_t my_conv_funct (my_enum_t value)
{
uint32_t result;
switch(value)
{
case CASE_A: result = 0; break;
case CASE_B: result = 1; break;
case CASE_C: result = 2; break;
default:
{
// error handling here
}
}
return result;
}
Alternatively (deviating from the rule):
uint32_t my_conv_funct (my_enum_t value)
{
static const uint32_t lut[] = { CASE_A, CASE_B, CASE_C };
for(size_t i=0; i<sizeof lut/sizeof *lut; i++)
{
if(lut[i] == value)
{
return i;
}
}
/* error handling */
return some_error_code;
}
This assuming that the amount of items isn't large, in which case a binary search might be more inefficient.
This in turn assuming that the enum constants don't correspond to 0, 1 and 2 in which case the whole function is nonsense.
The rationale for the MISRA C "single exit" Rule is because it is a requirement for the functional safety standards (eg IEC 61508 and ISO 26262).
It is also Advisory so can be disapplied if the circumstances so require.
My personal view is that a switch statement seldom needs multiple exits - it is easy to structure to avoid them... however there are situations (eg parameter validation) where it may make sense.
--
As an aside, use of assert() is non-compliant with MISRA C as it expands to abort() which is in breach of Rule 21.8 - this is also a very undesirable behaviour in an embedded system (and questionable in a hosted environment)...
--
See profile for affiliation.
The updated question has now been extended to include:
the default case should be never called if there are no errors (for example a programmer add another value in the enum and doesn't add a corresponding case
another options would be to remove the default at all but that violates another misra rule
I disagree...
The default is there as an error trapping mechanism - especially in real-time/embedded systems, data values may change unexpectedly (cosmic rays anyone) and it is a brave real-world engineer that does not protect against the unexpected.
How often has a default or else clause containing a comment /* Can never reach here */ actually been reached?

switch cases and one global variable for each case

I am dealing with a issue with switch cases.
Explanation of the program:
main(argc,argv).
argv leads to cases in a switch statement. Depending on the input, the according case will be entered and the corresponding function will be executed. -> Output is always a struct, with different content. More than one input (i.e. main.c case1 case3) is allowed-> executed both cases.
my problem is dealing with the passing of these data's and save it in a global variable, in order to print the collection. Inside of a case, I am passing the local results to the global variable, but after the break statement of the case, the global starts with NULL again and doesn't contain the info's of the executed case.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "m.h"
output* print;
int main(int argc, char* argv[])
{
output_g* global; // global_struct
if(argc > 1)
{
global= create_global(argc-1); // allocation for global struct
for(int j = 0; j < argc; j++)
{
switch (atoi(argv[i]))
{
case 123:
{
output* print= 123();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 456:
{
output* print= 456();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 789:
{
lfnr++;
output_1* print_liste = 789();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
default:
break;
}
print_global_struct(file,globale_liste);
delete_global(globale_liste);
}//End for-Schleife
}// End If
return 0;
}
a) If I understood you correctly, you don't understand the switch statement :)
A switch statement is similar to nested if statements.
so..
int x = 10;
switch (x)
case 1:
//does not happen, x is not 1
case 10:
//happens ...
after all that x is still 10, unless you changed it in the case statements explicitly. The cases just check to see IF x is a value, it does not SET a value. The same is true for any other variable in your code, the above code would not modify y either, unless you explicitly assign it inside a case it won't change.
b) it is best if you DO NOT declare locals in a case statement. They can become very wonky. The standard c++ rules work: variables declared inside {} pairs are scoped to inside that {} pair, so proper use of them will properly give the correct scope for each case. So it will work as expected if you apply braces. You should NOT declare a local in one case and use it in another, even if you can get it working (you can) it is error prone in that editing the code later can break things, the code can be confusing to read and work with, and its just generally a bad idea.
an example:
int main()
{
int x = 3;
switch(x)
{
case 1: int y;
case 2: y = 3;
case 3: y = 5;
cout << y << endl;
};
}
that compiled and ran for me, printing 5.
It worked fine -- I did not expect that, using g++ c17 options.
I still think it is a bad thing to do as far as reading and following the intent.
if you put {} around the int y statement, it does NOT compile anymore.
If you put breaks after the case 1 and case 2, it does NOT compile anymore.
so it is 'fragile' to being edited, at the very least, to do this.
c) run time won't lose anything. Ive had programs that ran for months on end. Being in a case has no effect on this either. The risk of losing variables is the 'ram' risk that all programs face... if a long running program is killed by power outage or malfunction etc you lose anything not saved to a file and have to start over. Long running programs should save their state periodically to protect against this.

Dealing with non-option arguments in getopt before options are checked

I am writing a program and I want to get the non-option arguments before checking the flags.
For example, if the arguments are ./a.out -a -b 50 filename
I want to use filename and then do task_a() and/or task_b()depending on the flags. filename can be any argument in argv[]
int opt;
float value;
while ((opt = getopt(argc, argv, "ab:")) != -1)
case 'a':
task_a(filename);
break;
case 'b':
value = atof(optarg);
task_b(filename, value);
break;
So basically I need to extract filename before using it in my tasks. How can I implement this?
getopt will pass you the command line arguments in the order that it finds them on the command line. This is generally NOT the order that you want to process them.
Instead, have your program set its options first before performing the operations - so something like ( given #include <stdbool.h> ) :
// Set the defaults
bool doTaskA = false;
book doTaskB = false;
float brightness = -1;
int opt;
float value;
while ((opt = getopt(argc, argv, "ab:")) != -1) {
case 'a':
doTaskA = true;
break;
case 'b':
doTaskB = true;
brightness = atof(optarg);
break;
}
filename = ....,,
if (doTaskA) {
task_a(filename);
}
if (doTaskB) {
task_b(filename, brightness);
}
I chose the name “brightness” as a meaningful attribute name - naturally you should choose your own. As good practice, do NOT name your variables “optionA” or some such - variable names should describe what they ARE, not the specific implementation details.
Always imagine that your options can change letters over time (what is now option “a” might become option “R” in six months time) - such changes should not affect anything except the “getopt” arguments and “case” statements.
EDITED TO CHANGE :
I originally wrote this with “if (brightness >= 0.0)”, but decided that in general a separate doTaskB variable is cleaner, more explicit approach that does not limit the possible values of the argument.

Is there any better implementation for this switch case construct?

I'm working on an embedded system where a register hast to be accessed and after that to be incremented to achieve the result I'm looking for, since the machine is notifying and configured to react on my access and changing or not changing the flag. So the switch's argument has to be kept as it is, since it would otherwise change the behaving of the embedded system.
But there may occur a situation where I don't want to get any of the cases get invoked. But I still need to acces and increment the argument of the switch.
(More indepth I'm converting a sequence of analog values to digital values conversions step by step. The index is used to stay synchronized with the current conversion and relating it with the corresponding case to handle the figure correct. There may occur a state in which the index desynchronisizes to the current conversion so the sequence of conversions must be run through without any of the cases getting invoked (to prevent setting wrong data) untill the sequence is finished and the resynchroinisation can get performed)
The way I'm currently doing this is this:
switch (RunIndex++)/*RunIndex may only be accessed one time per execution
of this construct and has to be incremented in the same step. thats given.*/
{
if (RunIndexSyncedWithADCensured == false)
{
break;
}
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
case 1:
Case1RelatedData = SomeOperationsForCase1(RawData);
break;
case 2:
Case2RelatedData = SomeOperationsForCase2(RawData);
break;
default:
RunIndex = 0;
break;
}
This construct does the job but it looks like it is a bit controversial and I don't feel well by considering about committing this into productinal code.
So is there a better looking way to achieve the same, without the need of additional variables or assignements?
note:
Also it may be relevant, that this is in the first part of a interupt function consisting of 2 parts.
The first part handles what has to happen if() a conversion is finished. The second part, what has additional to be done if() this conversion also ended the sequence. So it is no option to simply return from the function without getting into the second part. and there is currently no loop structure where an if(...)break; may break out. (What is also the reason why I'm putting the if inside the switch scope, as it is at least by standard a valid way to break out.)
Firstly, the if() inside switch() will never be executed.
Consider the below code snippet:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 2;
switch(i) {
if (i == 2) {
printf("I M HERE\n");
}
case 1:
printf("1\n");
break;
case 2:
printf("2\n");
break;
default:
printf("default\n");
break;
}
return 0;
}
For your code: you expect the string I M HERE to be printed. But that is not the case.
The output for the above code snippet is:
2
No statements before case/default(switch constructs): is executed inside switch
Now to answer for
I don't want to get any of the cases get invoked. But I still need to acces and increment the argument of the switch
Just move the if() outside to the switch().
if (RunIndexSyncedWithADCensured) {
switch (RunIndex++) {
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
/* Other cases here */
default:
RunIndex = 0;
break;
}
} else
RunIndex++;
Why not save the value first and then increment it and use the saved value in the switch? By the way this also includes two accesses, first to read the value from RunIndex and the second to increment it.
int runIndex = (RunIndex++);
if (RunIndexSyncedWithADCensured )
{
switch (runIndex)/*RunIndex may only be accessed one time per execution
of this construct and has to be incremented in the same step. thats given.*/
{
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
case 1:
Case1RelatedData = SomeOperationsForCase1(RawData);
break;
case 2:
Case2RelatedData = SomeOperationsForCase2(RawData);
break;
default:
RunIndex = 0;
break;
}
}
Since you are using adjacent index numbers, you could make an array of function pointers to replace the switch. That's what the optimizer will turn the switch into anyhow. So instead of your obscure switch, you get this:
if (RunIndexSyncedWithADCensured)
{
SomeOperationsForCase[RunIndex](RawData);
}
RunIndex++;
if (RunIndex > MAX)
{
RunIndex = 0;
}
Completely unrelated to the switch statement design: in case RunIndex is a sensitive volatile variable such as some hardware register, then you shouldn't use it directly in any form of computations. Make a copy of it:
volatile int RunIndex;
...
int index = RunIndex; // read from RunIndex
if (RunIndexSyncedWithADCensured)
{
SomeOperationsForCase[index](RawData);
}
index++;
if (index > MAX)
{
index = 0;
}
RunIndex = index; // write to RunIndex
This is standard practice for all such volatile variables.

Coverity warns on default initialization of local variables

There is a coverity warning type: UNUSED_VALUE. This is defined by tool under "Code maintainability issues"
UNUSED_VALUE: When a variable is assigned a pointer value returned from a function call and is never used anywhere else in the source code, it can not only cause inefficient use of resources but can also result in undetermined behavior. This checker identifies all variables that are never used anywhere else in the program after a value is assigned to them.
This checker seems to be picking up some of the good programming practice also as a warning.
My question is that is there some better way to do the things? Or should such a warning be ignored (and reported to Coverity team for any possible improvements)?
Example 1: default iniailization of local variables
int func()
{
int retval = SUCCESS; //COVERITY says: Unused value (UNUSED_VALUE)assigned_value: Value SUCCESS is assigned to retval here, but that stored value is not used before it is overwritten
retval = recvMessage(); //COVERITY says: value_overwrite: Value SUCCESS is overwritten with value fromrecvMessage
....
}
Example 2: setting pointer to NULL after memory is freed
void func2()
{
char *p = NULL;
....
p = alloc_mem_wrapper();
... do something
free_mem_wrapper(p);
p = NULL; //Coverity says: Unused value (UNUSED_VALUE)assigned_pointer: Value NULL is assigned to p here, but that stored value is not used
... do rest of the job (p is not used again)
}
In my case, 90% of all the warnings are of above nature only!
Why not do it like this:
int retval = recvMessage();
and this
char * p = alloc_mem_wrapper();
(Mostly) if you do not know how to initialise a variable you probably do not needed (where you defined it).
All above suggestions are good, but still people do stumble on this error and see it as a problem. I guess people relate it to a violation of good practice because they think it will appear in following scenario
int status = -1;
char c = getch();
switch(c){
case 'w': {
status = walk();
}
break;
case 's': {
status = sit();
}
break;
}
printf("Status %d\n", status);
Above, it makes total sense to declare status on top and print it once the code in between has updated it. However, Coverity does not report it UNUSED_VALUE in this scenario. It actually complains on following code
int status = -1;
int steps = 0;
char c = getch();
switch(c){
case 'w': {
status = walk();
steps = get_steps();
status = (steps > 0)?status:-1;
}
break;
case 's': {
status = sit();
}
break;
}
printf("Status %d\n", status);
Above, steps can simply be a scope variable. Hence, the Coverity error has more to do with the scope than initialization.

Resources