From: kishor on
Hi friends,

I have some doubt in using "if" "else" statements.


uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
{

if(int1 == 32)
{
if(int2 == 16)
{
if(int3 == 8)
{
return 0;
}
else
{
return 1;
}
}
else
{
return 2;
}
}
else
{
return 3;
}
}

======================= OR ==============================

uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
{
if(int1 != 32)
{
return 3;
}

if(int2 != 16)
{
return 2;
}

if(int3 != 8)
{
return 1;
}

return 0;
}

Which is the better method (for efficiency, readability or any other
reason)????.

Thanks & Regards,
Kishore.


From: Meindert Sprang on
"kishor" <kiishor(a)gmail.com> wrote in message
news:82727fda-0b47-446e-82f1-808f0d72b6d1(a)r5g2000prf.googlegroups.com...
> Hi friends,
>
> I have some doubt in using "if" "else" statements.
>
>
> uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
> {
>
> if(int1 == 32)
> {
> if(int2 == 16)
> {
> if(int3 == 8)
> {
> return 0;
> }
> else
> {
> return 1;
> }
> }
> else
> {
> return 2;
> }
> }
> else
> {
> return 3;
> }
> }
>
> ======================= OR ==============================
>
> uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
> {
> if(int1 != 32)
> {
> return 3;
> }
>
> if(int2 != 16)
> {
> return 2;
> }
>
> if(int3 != 8)
> {
> return 1;
> }
>
> return 0;
> }
>
> Which is the better method (for efficiency, readability or any other
> reason)????.

I find the latter more readable. Which is the most efficient depends on what
your compiler produces. Check the assemble listing for an answer.

Meindert


From: David Brown on
On 07/06/2010 10:49, kishor wrote:
> Hi friends,
>
> I have some doubt in using "if" "else" statements.
>
>
> uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
> {
>
> if(int1 == 32)
> {
> if(int2 == 16)
> {
> if(int3 == 8)
> {
> return 0;
> }
> else
> {
> return 1;
> }
> }
> else
> {
> return 2;
> }
> }
> else
> {
> return 3;
> }
> }
>
> ======================= OR ==============================
>
> uint16_t Func1(uint16_t int1, uint16_t int2, uint16_t int3)
> {
> if(int1 != 32)
> {
> return 3;
> }
>
> if(int2 != 16)
> {
> return 2;
> }
>
> if(int3 != 8)
> {
> return 1;
> }
>
> return 0;
> }
>
> Which is the better method (for efficiency, readability or any other
> reason)????.
>
> Thanks& Regards,
> Kishore.
>
>

It is up to /you/ to decide which is the most readable.

As to which is the most efficient, it depends on the target processor
and the compiler. If you think that the efficiency of this code is
important, then /you/ have to compile it and view the generated
assembly. It is quite possible that the compiler will generate the same
target code for both functions. But it may be a little different, and
that may affect the speed of the function - depending on the target
processor, the differences between "branch taken" and "branch skipped"
times, branch prediction logic (if any), caching, and the likelihood of
the different conditions being true or false.

Almost certainly, the efficiency is irrelevant - if not, you have much
bigger problems in store for you. So pick the format you think is most
readable and easiest to maintain.

From: D Yuniskis on
kishor wrote:
> I have some doubt in using "if" "else" statements.

First, how I would rewrite each of your examples
(indentation and spacing):

uint16_t
Func1(
uint16_t int1,
uint16_t int2,
uint16_t int3
) {
if (int1 == 32) {
if (int2 == 16) {
if (int3 == 8) {
return 0;
} else {
return 1;
}
} else {
return 2;
}
} else {
return 3;
}
}

> ======================= OR ==============================

uint16_t
Func1(
uint16_t int1,
uint16_t int2,
uint16_t int3
) {
if (int1 != 32) {
return 3;
}

if (int2 != 16) {
return 2;
}

if (int3 != 8) {
return 1;
}

return 0;
}

[I trade vertical space differently than many would :-/ ]

Next, some alternative ways of writing it:

uint16_t
Func1(
uint16_t int1,
uint16_t int2,
uint16_t int3
) {
if (int1 == 32) && (int2 == 16) && (int3 == 8) {
return 0;
}

if (int1 == 32) && (int2 == 16) && (int3 != 8) {
return 1;
}

if (int1 == 32) && (int2 != 16) {
return 2;
}

if (int1 != 32) {
return 3;
}

/* CAN'T HAPPEN */
}


uint16_t
Func1(
uint16_t int1,
uint16_t int2,
uint16_t int3
) {
if (int1 == 32) && (int2 == 16) {
return (int3 == 8) ? 0 : 1;
}

if (int1 == 32) {
return 2;
} else {
return 3;
}

/* CAN'T HAPPEN */
}

[I hope I haven't mangled the logic while cutting and pasting :< ]

The point being that you need to think about what you are trying
to accomplish. Presumably, you aren't testing generic variables
for specific generic values (unless this is a homework assignment).
Rather, I would assume something more along the lines of:

result_t /* SAFE_TO_CHANGE or otherwise */
safe_to_change_cutting_tool(
motorstate_t motor, /* STOPPED or otherwise */
toolstate_t toolhead, /* RETRACTED or otherwise */
carriage_t position /* HOME or otherwise */
) {
/* if motor is still running, don't do anything! */
if (motor != STOPPED) {
return MECHANISM_IN_MOTION;
}

/* motor == STOPPED */
if (toolhead != RETRACTED) {
return TOOL_STUCK_IN_WORKPIECE;
}

/* motor == STOPPED, toolhead == RETRACTED */
if (position != HOME) {
return INCORRECT_CARRIAGE_POSITION;
}

return SAFE_TO_CHANGE;
}

Putting some symbolic labels on the conditions makes a difference
in how a human would read it (with some thought, you can come
up with a different set of labels that would want to be read
using a different "code layout" -- think about it!)

> Which is the better method (for efficiency, readability or any other
> reason)????.

While reading the code, I like to know exactly what the conditions
are that apply to the stanza that I am reading at the time.
That can be done explicitly (e.g., list all of the conditions
in the "if") or implicitly (e.g., the above example assigns a
logical priority to the conditions which are being tested:
the motor being in motion overrides all other considerations,
etc.)

As to the efficiency of the generated code, that depends on
your compiler. Some are actually very clever and will
come up with essentially the same code for each version!
(YMMV).

Unless you have some overwhelming reason why "efficiency"
(size? speed??) is of paramount importance, try to
write the code so it is least likely to confuse a
reader seeing it for the first time. And, feel free to
add commentary explaining why you are making certain tests.
(as well as "notes to yourself" about what previous
tests have told you about the state of things "at this point"
in the function body -- i.e., my "/* motor == STOPPED */"
comments...)
From: Vladimir Vassilevsky on


kishor wrote:
> Hi friends,
>
> I have some doubt in using "if" "else" statements.
> Which is the better method (for efficiency, readability or any other
> reason)????.

A piece of code shall have only one entry point and only one exit point.


Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com