C, debugger breakpoints on simple if else statement - c

I'm very new to coding, I'm editing a simple C function in CodeBlocks. I'm getting a red error dot next to "else", I could't spot any problem with my code, perhaps its something I have overlooked. Please help, thanks!
int isZero (float f)
{
unsigned int u = *(unsigned int*)&f;
if ((u== 0x0) || (u==0x80000000) );
return 1;
else
return 0;
return (EXIT_SUCCESS);
}

Watch out for all semicolons. There's one more than you want.

You've got an extra semicolon there.
Remove the one from the end of if ((u== 0x0) || (u==0x80000000) );
The compiler reads the ; as a single statement doing nothing; and considers that the contents of the if block. The next statement is return 1;, which will always execute. When the compiler sees the else, it can't find the if that goes with it because that if block got closed with the first semicolon.
The compiler parses this as
int isZero (float f)
{
unsigned int u = *(unsigned int*)&f;
if ((u== 0x0) || (u==0x80000000)
/* do nothing */;
return 1;
else /* what does this go with? */
return 0;
return (EXIT_SUCCESS);
}

When you put a ; after an if clause it means that the if is an empty block.Therefore whether the statement is true or false the statement next to if is always excecuted.So your code
if ((u== 0x0) || (u==0x80000000) );
return 1;
evaluates to
if ((u== 0x0) || (u==0x80000000) )
{ //empty block
}
return 1; //always excecuted
Therefore the else part is never excecuted and the compiler does not see a if statement to relate this else to so you get an error.

Related

Trying to understand the logic of an IF statement

I'm trying to construct some Ada code, but to do so, I have to understand some C.
In net-snmp-5.8.1.pre2/apps/snmpbulkwalk.c and probably others, there is an if statement which I am trying to understand what is happening and to separate it out, thus:
if ((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid))) != 0) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
I get name_length < rootlen, I also get that memcpy always returns a pointer and never fails. From my poor eyesight it seems to say that if the < fails, it will then try the memcpy which always succeeds and then execute the contents of the IF block. But no... If that were the case, you could just put the memcpy inside the block.
No matter how I separate out the if statement, I can never get it to work the way it is already coded.
Your if does "short circuit" evaluation. It is basically of the form:
if (expression_A || expression_B)
do_something;
It evaluates expression_A, if it is true, expression_B is not evaluated. And, the if is taken (i.e. do_something is executed)
If expression_A is false, then expression_B is evaluated. If it is true, the if is taken
Restating the actual if code:
if (vars->name_length < rootlen) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
if (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
Restating the general case:
if (expression_A)
do_something;
else {
if (expression_B)
do_something;
}

A "--" operator in while loop function

I am coding in C on a IAR compiler and have two while loops:
i= 5;
do {
Task_sleep(1000);
}while(i-- && !Ready);
if (!Ready)
{
dprint("No ready response!");
return false;
}
And
i= 5;
do {
Task_sleep(1000);
i--;
}while(i > 0 && !Ready);
if (!Ready)
{
dprint("No ready response!");
return false;
}
The first will skip over the while loop and the second works properly. The "Ready" bool is set in another thread. The first loop will return false and the second will pass so Ready is not getting set to true.
I am thinking the compiler does not know how to handle the i-- in the while and is setting it to false. Is there something else that could be going on? With my setup I cannot step through the code in debug.
Edit Added to functions:
if(!Ready)
{
dprint("No Ready responce!");
return false;
}
Tested Ready as volatile, --i instead of i--, and removing Ready. All failed. Testing:
}while(((i--) > 0) && !Ready);
Still fails, it has to be the IAR compiler not reading the i-- properly and needs to have the -- operation removed from the while function. Let me know if you guys have anything else I can try but I feel confident in closing this issue.
You're confusing post-decrement with pre-decrement operators. The two operators are different. Both i-- and --i will decrement i. But their values are different. The value of i--, the post-decrement operator, is the old value of i. The value of --i, the pre-decrement operator, is the new value of i.
Your first code:
do {
Task_sleep(1000);
}while(i-- && !Ready);
Is equivalent to this:
int condition;
TOP:
Task_sleep(1000);
condition = (i != 0 && !Ready);
i = i - 1;
if (condition)
goto TOP
Your second code:
do {
Task_sleep(1000);
i--;
}while(i > 0 && !Ready);
is equivalent to this:
int condition;
TOP:
Task_sleep(1000);
i = i - 1;
condition = (i > 0 && !Ready);
if (condition) goto TOP;
The loops are different. i is decremented at a different time relative to the time the condition is evaluated, and the comparison on i within the condition is different.
Maybe you can try using volatile keyword to qualify variable i in the first version. I met a similar problem last week.

Standard idiom for executing a while loop one more time

Is there a pattern in C to execute a while loop one more time.
Currently I'm using
while(condition) {
condition = process();
// process() could be multiple lines instead of a function call
// so while(process());process(); is not an option
}
process();
which is horrible if process is of multiple lines and not a single function call.
The alternative is
bool run_once_more = 1;
while(condition || run_once_more) {
if (!condition) {
run_once_more = 0;
}
condition = process();
condition = condition && run_once_more;
}
Is there a better way?
Note: A do while loop is not a solution as it is equivalent to
process();
while(condition){condition=process();}
I want
while(condition){condition=process();}
process();
Per requests, a bit more specific code.
I want to fill buffer from another_buffer and get
(indexof(next_set_bit) + 1) into MSB while maintaining both masks and pointers.
uint16t buffer;
...
while((buffer & (1 << (8*sizeof(buffer) - 1))) == 0) { // get msb as 1
buffer <<= 1;
// fill LSB from another buffer
buffer |= (uint16_t) (other_buffer[i] & other_buffer_mask);
// maintain other_buffer pointers and masks
other_buffer_mask >>= 1;
if(!(other_buffer_mask)) {
other_buffer_mask = (1 << 8*sizeof(other_buffer[0]) -1)
++i;
}
}
// Throw away the set MSB
buffer <<= 1;
buffer |= (uint16_t) (other_buffer[i] & other_buffer_mask);
other_buffer_mask >>= 1;
if(!(other_buffer_mask)) {
other_buffer_mask = (1 << 8*sizeof(other_buffer[0]) -1)
++i;
}
use_this_buffer(buffer);
Because it's not a very typical thing to do, it's unlikely that there is a standard idiom for doing this. However, I'd write the code like this:
for (bool last = 0; condition || last; last = !(condition || last)) {
condition = process();
}
The loop will execute as long as condition is true and then one more time, or zero times if condition is false when the loop begins. I interpret your question as meaning that that is the desired behavior. If not, and you always want the loop to execute at least once, then do...while is the idiom you seek.
What about this:
int done, condition = 1;
for (;;) {
...
done = !condition;
condition = process();
if (done) break;
...
}
I am not suggesting this is a standard idiom, just an ad hoc hack.
I'd use this:
bool done = false;
do {
if (!condition) done = true;
condition = process();
} while (!done);
A much less readable hack, assuming condition is not predefined:
for (bool condition=true, done=false;
!done && (condition || done = true);
) {
condition = process();
}
I've had this same issue and my solution is:
Only if you know for sure you want to run process() at least once:
while(1){
process();
if(!condition()) break;
/*The loop breaks before bad things happen*/
things_you_want_to_happen_only_while_condition_is_true();
}
If you are not sure:
if(condition()){ /*Same as before, but it checks first*/
while(1){
process();
if(!condition()) break;
/*The loop breaks before bad things happen*/
things_you_want_to_happen_only_while_condition_is_true();
}
}
For example:
/*A pointer that goes over the string T from right to left.
It prints "Yes" when pointing at the character 'O' and "No" when not*/
char T[] = {'O', 'V', 'E', 'R', 'F', 'L', 'O', 'W', 0};
char *P = &T[strlen(T)-1]; /*We want the pointer to start at the last character of T*/
while(1){
if(*P=='O') printf("Yes\n");
else printf("No\n");
if(P==&T[0]) break; /*When it reaches the beginning of T, it stops*/
/*We only want the pointer to go further back if it is not in the beginning of T.
That's because we don't know what's before in the memory.*/
P--;
}
Your code is way more advanced than my level, but I came to this question as I had a similar difficulty on a problem set (I wanted the function to execute one last time) and I solved it like this:
define check_value as type_required;
while (check_value)
{
check_value = additional_output_from_process;
condition = process();
}
Would something like that work? In my problem I'm just taking a modulus so I can just run the process twice, system overhead really isn't a consideration.
This works in my example but it might just be a specific use case? I don't know, I'm literally only 6 months into coding.
I think what I'm trying to say is: introduce an additional value, and set the logical test so that the function output (operation) additional value = true. Then set the value of the additional value before you evalutate the function. The result function output (operation) additional value then will only be set to true after the loop has already run again.

Is it possible to execute both if and else part of an if --- else control statement? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Simultaneous execution of both if and else blocks
Is it possible to put some condition, so that both if and else part in an if ...else control statement can be executed without any warning or error ??
Do not use! ;-)
Yes, by forking.
if ( fork() ) {
printf("if\n");
}
else {
printf("else\n");
}
There are no real use cases to prefer the above code, unless it is for parallel execution.
No, there's no way to write a Schrödinger if clause.
You might be able to execute both with a goto, but it would never pass a code review.
Yes, it's possible:
#include <stdio.h>
#define else if (1)
int main(void)
{
int test = 1;
if (test == 1)
{
printf("if\n");
}
else
{
printf("else\n");
}
return 0;
}
#undef else
A note for newbies: Never do this in real life! Instead, think about your problem again...
What you probably wanted is :
#include <stdio.h>
int main(void)
{
int one_condition = 1;
int other_condition = 2;
if ((one_condition == 1) || (other_condition == 2))
{
printf("if\n");
}
if ((one_condition != 1) || (other_condition == 2))
{
printf("quasi-else\n");
}
return 0;
}
You can replace the else-path by having another if-clause with negated conditions. This gives you the possibility to override it with a second condition.
No, that is not possible (inside the same process).
Maybe you've misunderstood your problem.
If you want a code block to execute regardless of the condition, take it out of the if...else statement.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
else
{
//do something if a DOES NOT equal 484
}
//do something regardless of the outcome of the test.
}
In this example, ridiculous though it is, the last line is outside the condition statement, so will execute whether a == 484 or not, which seems to me to be the same as making c trigger your else block regardless of the if test succeeds.
Of course, else blocks are not mandatory, so if you don't care what happens if your condition fails, then simply don't have an else block.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
//do something regardless of the outcome of the test.
}
I assume you're trying to have both branches of this sort of statement execute?
Dim X As Boolean
X = False
If X = True Then
...
Else
...
End If
You could get it to execute using GoTo ... but that goes against good programming practice.
Dim X As Boolean
X = False
If X = True Then
...
Goto ElseStuff
Else
ElseStuff:
...
End If
Instead of that you should write separate procedures / functions to accomplish the behavior you'd like to have execute in both statements ... or simply put the code which should execute in all cases outside of the If block.
That would be functionally equivalent to using the GoTo, plus it makes it clear to anybody else.

Is it possible to execute a "C" statement without a semicolon

Post an example to execute a "C" statement without semicolon( ; )
This line is a statement:
while (0) { }
You can an expression in an if() as long as it evaluates to a scalar (integer, floating point number or pointer).
if (expr, 0) {}
According to the C grammar, expr is an expression. if(expr){} is a selection_statement, so this would match the bill.
Note that the ,0 isn't always necessary since the body of the if() is empty. So these would be equivalent statements, if expr returns a scalar:
if (expr) {}
while (expr, 0) {}
while (expr && 0) {}
while (expr || 0) {}
All would evaluate the expression once.
Wrong answer
... with a new right answer below.
int main(void)
{
}
The pair of braces in the definition of main is a compound-statement which is one of the valid forms for a statement.
Edit: although a statement can be a compound-statement, and a function-body consists of a compound-statement, when the compound-statement is a function-body, it's not a statement.
Edit, Edit:
This program does contain a statement which is executed, though:
int main(void)
{
if (1) {}
}
Use this function:
__asm {
mov al, 2
mov dx, 0xD007
out dx, al
}
{ }
At least 15 characters are required to post an answer...
if (i=2) {} // give `i` a value
Even whole program (my GNU C built it despite result code returned is undefined).
The question is WHY?
/* NEVER DO THIS!!! */
int main()
{
{}
}
And in C++ we even can stabilize return code by this simple stack trick with variable
(yes, it is dirty, I understand but I think it should work for most cases):
/* NEVER RELY ON SUCH TRICKS */
int main()
{
if (int i=0) {}
}
int main()
{
// This executes a statement without a semicolon
if( int i = 10 )
{
// Call a function
if( Fibonacci(i) ) {}
}
// I have made my point
return 0;
}
int Fibonacci(int n)
{
return (n == 2) ? 1 : Fibonacci(n - 2) + Fibonacci(n - 1);
}
#define _ ;
int main()
{
return 0 _
}

Resources