Go Down

Topic: 0 == 2048 ??? (Read 794 times) previous topic - next topic

Malvineous

Hi all,

I've got a bit of a weird problem building my library and I can't figure it out.  I have a function that the external code calls, and this function returns zero.  The external code has a while loop that checks this return value and breaks out of the loop when it's zero.

So you'd think the loop would never run, right?  Well the Arduino locks up in the loop...

Code: [Select]

uint8_t get_value() {
 return 0;
}
void external_function() {
 while (get_value()) {
   // do stuff
 }
}

Given that the code locks up only when the while loop is present I put a debugging command in to find out what get_value() is returning, and it came out as 2048!  That's why the loop runs forever.  How you get 2048 from a "return 0;" is beyond me though...any suggestions??

Maybe something to do with a uint8_t being cast to some other type?

Malvineous

Why is it that you can stuff around with a problem for ages and as soon as you post it on a forum you stumble across the solution?

Well I'm not sure *why* it works, but you have to explicitly cast the return value to the same type as in the function definition:

Code: [Select]

while ((uint8_t)get_value()) {

You'd think the compiler would do that automatically, but apparently not...

Maybe it's got something to do with the external code being 'extern C' and the get_value() function is not?

Coding Badly


Does a char return value make any difference...

Code: [Select]
char get_value() {

Malvineous

Unfortunately now I can't tell :-(  It works as a char, but it is also working now if I take out the uint8_t cast.  Perhaps that memory location is all zero now so it will work until it changes again...?

Coding Badly

Quote
Perhaps that memory location is all zero now so it will work until it changes again...?

If it's a code generation bug that could certainly be the case.  If it happens again, please report back.

Or, if you post the Sketch, someone may be willing to dig through the assembly to determine if there's still a problem.

graymalkin

Because the Arduino can't do booleans (they are handled as ints) the while statement may as well be while(false){} right?

Coding Badly

Quote
Because the Arduino can't do booleans

Why do you think it can't?  What do you mean by "booleans"?  Are you referring to the bool datatype?

Quote
(they are handled as ints)

Are you saying the bool datatype is implemented as an int?

graymalkin

Yeah, I am... 0x1 and 0x0 (true false) the same way HIGH and LOW are handled (0x1 and 0x0 respectively.)  I could be mistaken but I thought this is how Arduino stores these bool types.  

Regards,
/me

Coding Badly

The bool datatype is stored in a single byte.  It's most related to the uint8_t or byte datatypes.  true is stored as 0x1 and false is stored as 0x0.

Quote
Because the Arduino can't do booleans (they are handled as ints) the while statement may as well be while(false){} right?

In C(++), any thing that can be coerced into a bool can be used for a conditional expression...


 int i;
 while ( i ) {  // if i is not zero, the loop executes (i is quietly coerced to a bool by comparing it to zero)

 char ch;
 while ( ch ) {  // if ch is not zero, the loop executes

 float f;
 while ( f ) {  // if f is not zero, the loop executes (f has to be EXACTLY zero)

 char* s;
 while ( s ) {  // if s is not NULL, the loop executes


So, Malvineous' original expression...

 while (get_value()) {

...can be rewritten like this with the same results...

 while ( get_value() != 0 ) {

Go Up