Pages: [1]   Go Down
Author Topic: Obscure infinite for loop.  (Read 1365 times)
0 Members and 1 Guest are viewing this topic.
Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Any suggestions why this would result in an infinite loop? Is there something about char that has changed with regards to the due.

Code:
char i;
byte mask = 0x80;
for (i = 7;i >= 0; i--){
#ifdef _LIB_SAM_
delayMicroseconds(1);
#endif
digitalWrite(_SCLK, 0); //Clock 0
digitalWrite(_SDATA, data & mask); //Send a bit
mask >>= 1;
#ifdef _LIB_SAM_
delayMicroseconds(1);
#endif
digitalWrite(_SCLK, 1); //Clock 1
Serial.println(i);
}
Logged

~Tom~

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Answered my own question. It would appear that char is now unsigned by default? It would be useful if that was mentioned somewhere!
Logged

~Tom~

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8601
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought char has always been unsigned  smiley-confuse

Anyway that's a good reason to use the uintX_t types.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Edison Member
*
Karma: 67
Posts: 1656
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the original C standard the char type was not specified as signed or unsigned.  This presented problems when char was used as a number.

Rather than change the behavior of char in existing implementations, the standards committee added two new types, signed char and unsigned char.  So now there are three types of char.  

So you should never use char as a numerical type, only unsigned char or signed char.

It is even possible that two compilers for a given machine will have different numerical behavior for char.

You can have three overloaded functions, f(char), f(signed char), and f(unsigned char).

For all other integer types there are two types, for example int is the same type as signed int.  You can only have two overloaded functions with f(int) being the same as f(signed int).

Edit: I just remembered that with gcc you can have "char" signed or unsigned with flags -funsigned-char or -fsigned-char.

« Last Edit: December 08, 2012, 08:24:11 pm by fat16lib » Logged

Dallas, TX USA
Online Online
Faraday Member
**
Karma: 70
Posts: 2739
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I ran into something very similar to this a little over a year ago and got into some serious C standard "discussions" over
how incrementing chars are handled in loops.
Here is the AVR freaks thread:
www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=111837
The standard does have some areas that are not specified to allow leniency for implementors.
The problem I had is that depending on how the char variable was declared, automatic vs static
or the level of optimization used or whether additional functions were passed the variable as an argument
varies how the increment of the "char" type is handled and subsequently tested or passed to a sub function.
In my book , it is case of overly aggressive optimization generating incorrect code in certain
circumstances.
However it technically can't be be considered as wrong because
the standard doesn't explicitly state how to handle math on type "char" for all cases.
So the compiler guys can always just claim that the unexpected (wrong) behavior was undefined anyway.

My beef was that while a standard may claim that a particular behavior is unspecified, it should
at least be consistent within the implementation.

--- bill
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to add some spice on this thread, another differences between AVR and ARM is that ARM is a 32bit processor, so, if you are used to work with char due to program size limitations, now with the Due, I guess you will need to change your habits,

Read here: Efficient C Code for ARM Devices, also here for a different point of view.

Enjoy and have a nice day.

--- Ricky
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just to add some spice on this thread, another differences between AVR and ARM is that ARM is a 32bit processor, so, if you are used to work with char due to program size limitations, now with the Due, I guess you will need to change your habits,

Read here: Efficient C Code for ARM Devices, also here for a different point of view.

Enjoy and have a nice day.

--- Ricky
That makes for interesting reading. It may also explain why the Due runs my Nokia LCD slower than an 16MHz AVR. I think I may have to add many more #if #else statements.

EDIT:
That improved the speed slightly (switching all chars to ints, and unsigned chars to unsigned ints), though it is still slower, perhaps it is due to the differences between digitalWrite() for the Due, and direct port access for AVR.
« Last Edit: December 09, 2012, 06:40:29 pm by Tom Carpenter » Logged

~Tom~

Pages: [1]   Go Up
Jump to: