views:

421

answers:

7

If Im trying to check an input 5 byte array (p) against a 5 byte array stored in flash (data), using the following function (e2CheckPINoverride), to simply return either a true or false value. But it seems, no matter what I try, it only returns as 'false'.

I call the function here:

if (e2CheckPINoverride(pinEntry) == 1){
  PTDD_PTDD1 = 1; 
}
else{
  PTDD_PTDD1 = 0; 
}

Here is the function:

BYTE e2CheckPINoverride(BYTE *p)
{
    BYTE i;
    BYTE data[5];

if(e2Read(E2_ENABLECODE, data, 5)) {
    if(data[0] != p[0]) return FALSE;
    if(data[1] != p[1]) return FALSE;
    if(data[2] != p[2]) return FALSE;
    if(data[3] != p[3]) return FALSE;
    if(data[4] != p[4]) return FALSE;
}
return TRUE;
}

I have already assigned true and false in the defines.h file:

#ifndef TRUE
    #define TRUE ((UCHAR)1)
#endif

#ifndef FALSE
    #define FALSE ((UCHAR)0)
#endif

and where

typedef unsigned char   UCHAR;

when i step through the code, it performs all the checks correctly, it passes in the correct value, compares it correctly and then breaks at the correct point, but is unable to process the return value of true?

please help?

+4  A: 
#define TRUE 1
#define FALSE 0

Forget the unsigned char. You can go with the premise that in c 0 is false everything else is true

fmsf
+2  A: 

Probably not going to solve your problem, but you should write:

PTDD_PTDD1 = e2CheckPINoverride(pinEntry) ? 1 : 0;

Also, you are mixing BYTEs and UCHARs (even though they are probably the same)

Tuomas Pelkonen
or even just PTDD_PTDD1 = e2CheckPINoverride(pinEntry);
David Gelhar
@David Well technically boolean true is a non-zero value, and if PTDD_PTDD1 should be either 0 or 1, I would not trust the return value and set PTDD_PTDD1 to 0 or 1 myself. Of course, if PTDD_PTDD1 is also a boolean value, then your proposal is correct.
Tuomas Pelkonen
Tuomas, you are making assumptions about what value the function will return in either implementation. To be correct you need to compare the returnvalue to the define: `PTDD_PTDD1 = (e2CheckPINoverride(pinEntry) == TRUE ? 1 : 0);`
Yannick M.
@Yannick I disagree, if you know that a function is returning a boolean value (non-zero when true) then e2CheckPINoverride(pinEntry) ? 1 : 0 is the correct way to do it.
Tuomas Pelkonen
Well, C does not have a boolean type. The function returns a BYTE (presumably an unsigned char in this context), and the value will either be the value of the `TRUE` or the `FALSE` define. Which in this case you are assuming will either be non zero, or zero.
Yannick M.
@Yannick M.: C has had a Boolean type for 10 years, it's called `_Bool`.
dreamlax
@Tuomas, yup, they are one and the same...typedef unsigned char UCHAR;typedef unsigned char BYTE;
RonnyJ
@Yannick M.: Also, the ternary operator is unnecessary, `(e2CheckPINoverride(pinEntry) == TRUE)` will evaluate to 1 if true and 0 if false.
dreamlax
Well, yes if you're going to include C99, but I was just noting that in all versions of C, booleans are just integers. You can't assume that a function that returns an unsigned char, should have its returnvalue interpreted as boolean.
Yannick M.
@dreamlax: It might be unnecessary, but it doesn't help readability. But that's another discussion.
Yannick M.
+1  A: 

Try narrowing this down by dispensing with the #define and just saying

return 1;

If that works, then something isn't working with your #define's.

David Gelhar
yeah, thxalready tried to eliminate that possibility with the following: if(e2Read(E2_ENABLECODE, data, 5)) { indicator = 1; if(data[0] != p[0]){ indicator = 0; return indicator; } if(data[1] != p[1]){ indicator = 0; return indicator; } if(data[2] != p[2]){ indicator = 0; return indicator; } if(data[3] != p[3]){ indicator = 0; return indicator; } if(data[4] != p[4]){ indicator = 0; return indicator; } } return indicator;no joy :(
RonnyJ
sorry thats a mess. im new to this forum, to create a code block, it says indent by at least four spaces? or a tab?doesnt seem to be doin the trick?
RonnyJ
To add a code block in comments use backticks to surround it (however keep in mind that comments are single line). But I suggest you elaborate further in your question.
Yannick M.
A: 

Your data array is never initialised so it has random values inside.

BYTE data[5];

So, you are comparing the elements from array p with random values from array data. It will return almost always FALSE.

Conclusion: Fill the data array with meaningful data.

kaciula
e2Read() probably does that part. Reads something into data. Maybe.
Michael Foukarakis
yup.here is e2Read() 'BYTE e2Read(BYTE address, BYTE *data, BYTE len) { BYTE n; for(n = 0; n < len; n++) *data++ = E2DATA[address + n]; return TRUE; }'
RonnyJ
Yes. I see that now. Sorry. Will be more careful next time.
kaciula
+2  A: 

If you return TRUE or FALSE, you should also check for them. Rewrite the if clause like this:

   if (e2CheckPINoverride(pinEntry) == TRUE) { // instead of '== 1'
Martin Wickman
This is a *really* poor idea, IMO. In C, any and all non-zero values are true, so you should either use `if (xxx != 0)` or just `if (xxx)`, *never* an explicit comparison to any other value.
Jerry Coffin
@Jerry - except here he is defining a macro TRUE==1, 'true' it would be wrong if he were testing the return value of the function.
Martin Beckett
@Martin: I have to disagree. Defining "TRUE" is perfectly fine, but should always be treated as a write-only value -- i.e. it's fine to set something to TRUE, but you still shouldn't compare against it.
Jerry Coffin
Yes, comparing to 'true' is bad. But here TRUE is a token he is defining in both the return and the test. It could be equal to "yellow cupcakes" and it would still make sense. Of course as soon as somebody comes in and adds a function that returns 'true' all bets are off.
Martin Beckett
A: 

IMO, you're creating a great deal of unnecessary complexity. I'd write the function something like this:

int e2CheckPINoverride(BYTE *p) {
    BYTE data[5];

    return e2Read(E2_ENABLECODE, data, 5) && 
        data[0] == p[0] &&
        data[1] == p[1] &&
        data[2] == p[2] &&
        data[3] == p[3] &&
        data[4] == p[4];
}

And the calling code becomes simply:

PTDD_PTDD1 = e2CheckPINoverride(pinEntry);
Jerry Coffin
yeah originally it was this:` if(e2Read(E2_ENABLECODE, data, 5)) {`` if(data[0] != p[0]) return FALSE;`` if(data[1] != p[1]) return FALSE;`` if(data[2] != p[2]) return FALSE;`` if(data[3] != p[3]) return FALSE;`` if(data[4] != p[4]) return FALSE;``}`return TRUE;`but it wasnt working, so I was just trying to be explicit as possible.Making the change suggested by Vlad (at the top, commented on my original question) has solved the problem, but Im still not sure why.
RonnyJ
A: 

Just a small example that I tested to work. I dont know the content of e2Read so I made just a dummy

#ifndef UCHAR
    typedef unsigned char   UCHAR;
#endif
#ifndef BYTE
    typedef  char   BYTE;
#endif
#ifndef TRUE
    #define TRUE ((UCHAR)1)
#endif
#ifndef FALSE
    #define FALSE ((UCHAR)0)
#endif
int e2Read(int myconst, BYTE* data, int num)
{
    int i;
    for(i=0;i<num;i++)
        *(data++) = 0; // You can change thisone to test different results.
    return 1;
}
BYTE e2CheckPINoverride(BYTE *p)
{
#define E2_ENABLECODE 3
    BYTE data[5];
    if(e2Read(E2_ENABLECODE, data, 5)) {
    if(data[0] != p[0]) return FALSE;
    if(data[1] != p[1]) return FALSE;
    if(data[2] != p[2]) return FALSE;
    if(data[3] != p[3]) return FALSE;
    if(data[4] != p[4]) return FALSE;
    }
    return TRUE;
}
int main(void)
{
    BYTE b[5] = {0,0,0,0,0};// You can change thisone to test different results.
    BYTE* pinEntry = b;
    if (e2CheckPINoverride(pinEntry) == 1){
        printf("Returned true\n");
    }
    else{
        printf("Returned false\n");
    }
    return 0;
}
eaanon01