What does it mean? "if(A==B==C)" in Freescale USB stack v4.0.3

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

What does it mean? "if(A==B==C)" in Freescale USB stack v4.0.3

2,277 Views
kai_liu
Senior Contributor I

I have to debug code and look into source code of Freescale USB stack (v4.0.3) because of my project.

In khci_kinetis.c::_usb_khci_atom_tr(), line 261, there is a statement I can not fully understand.

        if (USB_EVENT_SET == _usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1) == USB_OK)

        {

            break;

        }

#define USB_EVENT_SET 0x02

#define USB_OK 0x00

uint_16 _usb_event_wait_ticks(USB_EVENT_STRUCT_PTR, uint_32, uint_8, uint_16);

That statement means

     if (0x02==var==0x00) break;

What is it anyway? I guess the judgement will be evaluated from left to right. If var equals to 0x02, then it is 0x01 as True. Otherwise it is 0x00 as false, then the truth value is compared to 0x00 to get second turth result.

Am I right? I still get confused why Freescale use such statement.

I double checked with v4.1.1, the latest release USB stack, it changes to

       if ((USB_EVENT_SET == _usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1)) == USB_OK)

        {

            break;

        }

It makes things much easier and safer. However, I doubt why Freescale can not use much simpler statements such as

if (USB_EVENT_SET == _usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1))

or

if (USB_EVENT_SET != usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1))

Tags (1)
0 Kudos
Reply
8 Replies

1,266 Views
renatolaureano
Contributor I

NOTE: The original source code is:

if ((USB_EVENT_SET == _usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1)) == USB_OK)

Then, the original question is not :

if(A == B == C)

But is:

if( (A == B) == C)

0 Kudos
Reply

1,266 Views
bobpaddock
Senior Contributor III

You can try out code snippets if you are not sure what they do here:

Do-It-Yourself Example (C)

This is a demo of Gimpel's Lint program.

If you are  doing embedded code you should be using Lint to make sure there are no lurking bugs.

Their Bug-of-the-Month is educational: Gimpel Software Bug of the Month

Here is an example, with deliberate bugs,  you can copy into their demo analyzer:

/*lint -e438 Suppress 'unused' */

void main( void )

{

int A,B;

unsigned int C;

A = 0;

B = 1;

C = 2U;

if( A==B==C )

{

   A = B = C = 3U;

}

if( A == C )

  {

   C = 4;

  }

}

1,266 Views
cardoso
Contributor II

The break will execute if, and only if,  the three expressions have the same value.

0 Kudos
Reply

1,266 Views
JimDon
Senior Contributor III

>The break will execute if, and only if,  the three expressions have the same value.

This is not true.

Given A=0,B=0,C=0

A==B==C = (A==B) == C

A ==B = 1 (true)

1  == C (false)

The break will not execute.

Given A=1, B=0, C=0 the break will execute.

1,266 Views
kai_liu
Senior Contributor I

I hope any FAE from FSL can explain it to me.

Thanks.

0 Kudos
Reply

1,266 Views
VictorLorenzo
Contributor IV

It will be evaluated:

1) tmpAB = (A==B), resulting in a value with BOOLEAN type [0, 1];

2) result = (tmpAB == C), which expect C with same type as tmpAB: BOOLEAN.

The result will be TRUE (and break) when (A==B && C==1) || (A!=B && C==0), FALSE otherwise.

But for the values and expressions involved in the statements it seems to me more like a bug than a rare combination of NOT/XOR operations (which makes no sense as C is constant in the expression: USB_OK is 0).

As USB_OK is defined as zero (same as FALSE), the expression is simply equivalent to:

if (USB_EVENT_SET != _usb_event_wait_ticks(&khci_event, KHCI_EVENT_MASK, FALSE, 1))

{

    break;

}


Many thanks to Bob Paddock for mentioning the tool, this kind of tools come very handy for bringing light into obscure code.

0 Kudos
Reply

1,266 Views
JimDon
Senior Contributor III

There is no BOOLEAN type in "C".

While c99 does have a _Bool type, c99 is not widely used.

0 Kudos
Reply

1,266 Views
VictorLorenzo
Contributor IV

Yes Jim, that's correct, the existance or not of one C type called "BOOLEAN"/"bool"/"boolean"/"_Bool" is compiler implementation specific (some compilers for the embedded world already define and implement the boolean type, with variations in the name and decorators). Most compilers do not follow the standards in a strict manner (C99, C11, C89, C90, and so on).

BOOLEAN in this case was just a concept, also a compile time type checking rule (in some compilers and tools, as C is too relaxed), that at the end will always be processor and compiler dependant.

In most implementations the result of logical operators/operations is assumed to be one integer with value range from 0-to-1, only one bit out of the native word is used for simplifying the native code so instructions like bitwise AND/OR/XOR/CMP/etc. can be directly used, and in some other implementations it's simply tested as Zero/Not_Zero (any value but zero is TRUE) for taking advantage of dedicated processor core machine instructions/microcode.

0 Kudos
Reply