do ... while macro/function with different conditions - c

I have the following code:
/* some calculation */
do {
/* data acquire and calculation */
} while (CONDITION);
My condition looks like one of the following:
(( A || B ) && C )
( A && C )
Note that I use these conditions with different statements for A, B and C. However the pre-calculation and everything inside the loop is always the same. I use this block several times in my code and wondered if there is a possibility to put it in a define or in a function to let the code look cleaner.
Is there a nice and reasonable way to achieve the loop with different statements?
I already thought about a function call in a while loop like
while (DoMyLoop( CONDITION, calculationParams ));
But with this solution I wouldn't have the pre-calculation in my one-liner.
How can I get my code block in a nice one-liner (or more if necessary, as long as it's easy to understand and maintain)?
Some additional (maybe irrelevant) information:
In my loop I receive a byte array and depending on the situation I have to loop until a specific bit changes, therefore the A or B.
C is a timeout condition.
Here is some code with variables
unsigned char data[10] = { 0 };
long intervalMS = 0;
/* precalc */
gettimeofday( &stopTimeout, NULL );
gettimeofday( &startTimeout, NULL );
do {
receiveCall( data );
gettimeofday( &stopTimeout, NULL );
intervalMS = (stopTimeout.tv_sec - startTimeout.tv_sec) * 1000 +
(stopTimeout.tv_usec - startTimeout.tv_usec) / 1000;
} while ( (data[0] & 0x01) && intervalMS < 200);
The A part of the condition can also look like ((data[2] & 0x02) || data[3] == 0x12).

What about next solution?
for (precalculation (); CONDITION; somethingWith (calculationParams));
precalculation () is executed once, the CONDITION is evaluated at every iteration and somethingWith (calculationParams) take the place in of the incrementation. The body of the for loop is empty.
Pure C beauty.
Obviously, precalculation and somethingWith (calculationParams) must become a new function.

First of all, please note that do {} while(something) is equivalent to something=true; while something{}. The former saves a bit of extra execution in case you don't want the initialization part.
How can I get my code block in a nice one-liner
There is nothing wrong with your code. } while ( (data[0] & 0x01) && intervalMS < 200); is perfectly clear to me - another C programmer.
You check if the lsb is set and you check a timer interval. The only way this code could be improved would be to explain why you check the lsb - which you can do with a comment (do you check if a number is odd or do you read a bit in bit-field etc).
Now what you can and should do, is to put the whole snippet inside a function and give it a meaningful name. There's the nice one-liner.

Related

For loop should be well-formed

MISRA C-2012 Control Flow Expressions (MISRA C-2012 Rule 14.2)
misra_c_2012_rule_14_2_violation: The expression i used in the for loop clauses is modified in the loop body.
for( i = 0; i < FLASH; i++ )
{
if( name.see[i] == 0xFF )
{
name.see[ i ] = faultId | mnemonicType;
modify_expr: Modifying the expression i.
i = FLASH-1; /* terminate loop */
}
}
You aren't allowed to modify the loop iterator i inside the loop body, doing so is senseless and very bad practice. Replace the obfuscated code i = FLASH-1; with break;.
Misra C 2004 rule 13.6 (14.2 in the 2012 edition) says
Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
The code modifies i in order to finish the for loop (as the comment confirms). This is a violation of the rule.
Misra C 2004 rule 14.6 says:
For any iteration statement there shall be at most one break statement used for loop termination.
Hence you can replace the offending code with a simple break statement and still conform:
for (i = 0; i < FLASH; i++) {
if (name.see[i] == 0xFF) {
name.see[i] = faultId | mnemonicType;
break;
}
}
Yet Misra says you can only do this if there is a single break statement in the loop. What if you want to test 2 different cases, handle them differently and break the loop on each of them. Using 2 break statements seems an obvious choice, but for compliance you would need to add an extra variable do_break, set it in the places where you want to break and test it just once at the end of the body to execute the break statement. Not a very good practice IMHO...
Note these facts about Misra C coding standards:
Misra renumbered the rules from one edition to the next, a necessary change creating some confusion.
The rules are not available in open source. This would help spread some good practices, but arguably prevented some questionable ones.
This for loop
for( i = 0; i < FLASH; i++ )
{
if( name.see[i] == 0xFF )
{
name.see[ i ] = faultId | mnemonicType;
i = FLASH-1; /* terminate loop */
}
}
is not clear for readers of the code.
Even if you will write
for( i = 0; i < FLASH; i++ )
{
if( name.see[i] == 0xFF )
{
name.see[ i ] = faultId | mnemonicType;
break;
}
}
then using the break statement is not a good approach. Each code block should have one entry point and one exit point.
In fact what you need is to find an element that satisfies the condition
name.see[i] == 0xFF
and is such an element exists then change it.
So it is better to write a while loop instead of the for loop the following way
i = 0;
wjile ( i < FLASH && name.see[i] != 0xFF ) i++
if ( i != FLASH ) name.see[ i ] = faultId | mnemonicType;
The advantage of this approach is that the while loop as is can be formed as a body of a function that finds an element in the array. It will be enough just to add the return statement
return i;

Why does thread not recognize change of a flag?

I have a strange situation under C/Visual Studio on a Windows 7 platform. There is a problem from time to time and I spent a lot of time to find it. The problem is within a third party library, for which I have the complete code. There a thread is created (the printLog statements are from myself):
...
plafParams->eventThreadFlag = 2;
printLog("before CreateThread");
if (plafParams->hReadThread_p = CreateThread(NULL, 0, ( LPTHREAD_START_ROUTINE ) plafPortReadThread, ( void * ) dlmsInstance, 0,
&plafParams->portReadThreadID) )
{
printLog("after CreateThread: OK");
plafParams->eventThreadFlag = 3;
}
else
{
unsigned int lasterr = GetLastError();
printLog("error CreateThread, last error:%x", lasterr);
/* Could not create the read thread. */
...
...
return FAILURE;
}
printLog("SUCCESS");
...
...
The thread function is:
void *plafPortReadThread(DLMS_GLOBALS *dlmsInstance)
{
PLAF_PARAMS *plafParams;
plafParams = (PLAF_PARAMS *)(dlmsInstance->plafParams);
printLog("start - plafPortReadThread, plafParams->eventThreadFlag=%x", plafParams->eventThreadFlag);
while ((plafParams->eventThreadFlag != 1) && (plafParams->eventThreadFlag != 3))
{
if (plafParams->eventThreadFlag == 0)
{
printLog("exit 1 - plafPortReadThread, plafParams->eventThreadFlag=%x", plafParams->eventThreadFlag);
CloseHandle(plafParams->hReadThread_p);
plafFree((void **)&plafParams);
ExitThread(0);
break;
}
}
printLog("start - plafPortReadThread, proceed=%d", proceed);
...
Now, when the flag is set before the while loop is started within the thread, everything works OK:
SUCCESS
start - plafPortReadThread, plafParams->eventThreadFlag=3
But sometimes the thread is quick enough so the while loop is started before the flag is actually set within the outer part.
The output is then:
start - plafPortReadThread, plafParams->eventThreadFlag=2
SUCCESS
Most surprisingly the while loop doesn't exit, even after the flag has been set to 3.
It seems, that the compiler "optimizes" the flag and assumes, that it cannot be changed from outside.
What could be the problem? I'm really surprised. Or is there something else I have overseen completely? I know, that the code is not very elegant and that such things should better be done with semaphores or signals. But it is not my code and I want to change as little as possible.
After removing the whole while condition it works as expected.
Should I change the struct or its fields to volatile ? Everybody says, that volatile is useless in our days and not needed anymore, except in the case, where a memory location is changed by peripherals...
Prior to C11 this is totally platform-dependent, because the effect you are observing is due to the memory model used by your platform. This is different from a compiler optimization as synchronization points between threads require the compiler to insert barrier instructions, instead of, e.g., making something a constant. For C11 for section 7.17.3 specifies the different models. So your value is not optimized out statically, thread A just never reads the value thread B wrote, but still has its local value.
In practice many projects don't use C11 yet, and thus you will likely have to check the documentation of your platform. Note that in many cases you don't have to modify the type of the variable for the flag (in case you can't). Most memory models specify synchronization points that also forbid reordering of certain instructions, i.e. in:
int x = 3;
_Atomic int a = 1;
x = 5;
a = 2;
the compiler will often have to ensure that x has the value 3 when a has the value 1, and that when a is assigned the value 2, x will have the value 5. volatile does not participate in this relationship (in the C/C++ 11 models - often confused because it does participate in Java's happened-before), and is mostly useless, unless your writes should never be optimized out because they have side-effects such as a LED blinking which the compiler can't understand:
volatile int x = 1; // some special location - blink then clear
x = 1; // blink then clear
x = 1; // blink then clear

The meaning of a single & in an if statement

Came across a weird notation today while reading through some C code
Can anyone explain to me what the line do?
if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}
if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}
& is Binary And Operator. & is applied to every bit of both the variables .It checks ,
if result of dwEvent & EV_RXCHAR is non-zero then cs.cbInQue is checked if it is non-zero or not .
If both the conditions are true code in if block is executed .
if result of dwEvent & EV_RXCHAR is zero then without checking cs.cbInQue , code in else block is executed if present.
It masks (performs binary AND operation) dwEvent with EV_RXCHAR, checks if the result is non-zero, checks if cs.cbInQue is non-zero, if both are true, executes code in conditional statement.
This is not necessarily a "weird" notation. Many programmers use it as a shortcut instead of specifying (x & y) != 0.
It is a bitwise operation. You can read it here. link
Its short form to check if the any of the bits EV_RXCHAR are set by checking getting out those bits first (dwEvent & EV_RXCHAR). Then if any of these are set it
would also check if cs.cbInQue is also set then do the stuff.
eg:
unsigned int x = dwEvent & EV_RXCHAR;
if (x !=0)
if (cs.cbInQue != 0)
{ /* do stuff */}

C - While and IF statements - Trying to timeout after X time

I am having difficulties with the below code;
int i = 0;
int x = 0;
int ch ;
int n;
while((i < sizeof(buffer) - 1) && (x < (TIMER_FREQ*30)))
{
//getkey_serial0 returns either a (int)character or 0 if nothing on
//UART0
if((ch = getkey_serial0) == 0)
{
x++; //Increment X as there is nothing being received.
}
else
{
if(ch == '\n')
{
n++;
}
if(n < 8){ //Yes I can simplify this but for some reason
} //I only just noticed this :/ Anyway, it is
else{ //just here to avoid saving info I don't need
buffer[i] = ch ;
i++;
}
}
}
As the input it is reading in is the results of a wireless scan the number of entries scanned can vary greatly, and so I need to be able to avoid infinitely looping.
Originally I just read up to 11 \n's but this was rubbish as I kept missing SSID's which I needed, so I decided I needed some sort of timer or method to help me break after X amount of time.
TIMER_FREQ is defined as 10.
Clearly I am doing something stupid so any suggestions or tips would be greatly appreciated.
I generally prefer suggestions to help me try and think out the problem as opposed to fixed code posts :) I always seem to miss something simple despite my best efforts!
Thanks
EDIT: I should mention, this is on an embedded system (ARM7)
You should have access to a general purpose timer interrupt -- commonly called sys_tick().
The general practice in such "bare metal" applications is to configure the interrupt to fire every n milliseconds (10 ms is frequently used on my Cortex M3). Then, have the ISR update a counter. You'll want to ensure the counter update is atomic, so use a 32-bit, properly-aligned variable. (I'm assuming your processor is 32-bit, I can't recall for certain). Then your "application" code can poll the elapsed time as needed.
BUT - this timer discussion might be moot. In my ARM9 applications, we tie an interrupt to the UART's receive buffer. The associated ISR captures the keystroke and then performs any buffer management. Is that an option for you?
Do you really mean:
if((ch = getkey_serial0) == 0) { ...
Or do you actually mean:
if((ch = getkey_serial0()) == 0) { ...
If the latter, this is why your program never returns zero as you are giving it a function pointer. Does your program have many warnings at build?
If you want to time things, look into time(). It will let you see the system's wall clock, so you can determine if too many seconds have elapsed.

How to NOT use while() loops in verilog (for synthesis)?

I've gotten in the habit of developing a lot testbenches and use for() and while() loops for testing purpose. Thats fine. The problem is that I've taken this habit over to coding for circuits which should be synthesizable. XST and others refuse to synthesize code (without additional modification to synthesis parameters) such as:
while (num < test_number)
begin
.
.
.
num = num+1;
end
This is bad coding style because to the synthesizer test_num is an int with value 2^32! or it sees it as unbounded parameter. Either way, its a bad coding habit. But I'm so used to doing this in C and testbenches. What would be the equivalent synthesizable of code of the above code segment?
Thanks!
Synthesis tools vary but generally a loop can be synthesized so long as the number of iterations is known a to the synthesis tool. So,
for ( i = 0; i < 10; i = i + 1 )
is OK because the tool knows there are 10 loop iterations. But
reg [10:0] r;
for ( i = 0; i < r; i = i + 1 )
is not OK because r is a variable r's value is unknown at synthesis time.
Think of loops in RTL code as creating a known fixed number of copies of a piece of logic.
You need to have a clock to control it to start.
always #(posedge clk or negedge rst_n)
if (!rst_n)
num <= 32'b0; // or whatever your width is.
else
if (num < test_number)
num <= num + 1'b1;
If your synthesis tool does not support while or for loops, then don't use a loop. Just expand your code out.
wire [1:0] addr;
reg [3:0] wren;
always #(posedge clk) begin
wren[0] <= (addr == 2'd0);
wren[1] <= (addr == 2'd1);
wren[2] <= (addr == 2'd2);
wren[3] <= (addr == 2'd3);
end
I am unfamiliar with XST, but some synthesis tools do support loops (Synopsys, for example).

Resources