Go to Post Good teams get picked, great teams want to do the picking... - Dave McLaughlin [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 13-01-2004, 00:40
Larry Barello Larry Barello is offline
http://www.barello.net
#0492 (Titan Robotics Club)
Team Role: Mentor
 
Join Date: Jan 2002
Location: Bellevue, WA
Posts: 85
Larry Barello has a spectacular aura aboutLarry Barello has a spectacular aura about
Whacky C Complier behavior

Beware! The compiler assumes constants are of type "char"

For example, this will generate no errors and give you -12 as the results!

int InitFoo = (100 * 5);

To get the right answer, you need to cast the 100 as an int:

int InitFoo = (int)100 * 5;

Sigh.

P.S. - floating point constants are completely screwed up. Not even casting seems to help.

Last edited by Larry Barello : 13-01-2004 at 00:51.
  #2   Spotlight this post!  
Unread 13-01-2004, 08:26
Unsung FIRST Hero
Mike Betts Mike Betts is offline
Electrical Engineer
no team
Team Role: Engineer
 
Join Date: Dec 2001
Rookie Year: 1995
Location: Homosassa, FL
Posts: 1,442
Mike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond repute
Re: Whacky C Complier behavior

Larry,

2 issues here...

You are doing an implicit initialization. Never a good idea in an embedded system.

Make it:

int InitFoo;

for your declaration and then

InitFoo = (100 * 5);

in your initialization routine.

Secondly (IMHO), you really do not want to do floating point... I have posted about this in other threads.

Good luck.
__________________
Mike Betts

Alumnus, Team 3518, Panthrobots, 2011
Alumnus, Team 177, Bobcat Robotics, 1995 - 2010
LRI, Connecticut Regional, 2007-2010
LRI, WPI Regional, 2009 - 2010
RI, South Florida Regional, 2012 - 2013

As easy as 355/113...
  #3   Spotlight this post!  
Unread 13-01-2004, 09:32
john atwood john atwood is offline
Registered User
#0997 (Zip Ties and Electrical Tape)
 
Join Date: Dec 2002
Location: Corvallis, OR
Posts: 1
john atwood is an unknown quantity at this point
Re: Whacky C Complier behavior

Quote:
Originally Posted by Mike Betts

2 issues here...

You are doing an implicit initialization. Never a good idea in an embedded system.

Make it:

int InitFoo;

for your declaration and then

InitFoo = (100 * 5);

in your initialization routine.

Secondly (IMHO), you really do not want to do floating point... I have posted about this in other threads.

Good luck.

The initialization looks pretty explicit to me.
Also, why waste code space and start up time
doing math the compiler can do.

The wacky behavior is a feature, where C18 intentionally departs from ISO standard behavior
for efficiency reasons. See section 2.7.1 of the C18 users guide.

To change the behavior, use the -Oi command line option, which can be set in MPLAB under Project->Build Options->Project->(tab)MPLAB C18->(check)Enable Integer Promotions.


John

Last edited by john atwood : 13-01-2004 at 09:37.
  #4   Spotlight this post!  
Unread 13-01-2004, 10:06
Larry Barello Larry Barello is offline
http://www.barello.net
#0492 (Titan Robotics Club)
Team Role: Mentor
 
Join Date: Jan 2002
Location: Bellevue, WA
Posts: 85
Larry Barello has a spectacular aura aboutLarry Barello has a spectacular aura about
Re: Whacky C Complier behavior

Quote:
Originally Posted by john atwood
...

The wacky behavior is a feature, where C18 intentionally departs from ISO standard behavior
for efficiency reasons. See section 2.7.1 of the C18 users guide.

To change the behavior, use the -Oi command line option, which can be set in MPLAB under Project->Build Options->Project->(tab)MPLAB C18->(check)Enable Integer Promotions.


John
Thanks!

Can you explain why not promoting to integer is more efficient? Or does that impact run time calculations even though the target may be a char? Can I override the promotion by explicitely typing intermediate values in an expression?

P.S. I figured out the Floating point problems: One has to tell MPLAB that the floating point representation is "MCHP" not ieee - then things display Ok. Unfortunately that only seems to work in the "watch" window properties. In the regular listings, hovering the cursor over the variable will return gibberish.

Last edited by Larry Barello : 13-01-2004 at 10:25.
  #5   Spotlight this post!  
Unread 21-01-2004, 10:43
WizardOfAz's Avatar
WizardOfAz WizardOfAz is offline
Lead Mentor
AKA: Bill Bennett
FRC #1011 (CRUSH)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Tucson, AZ
Posts: 101
WizardOfAz will become famous soon enough
Send a message via AIM to WizardOfAz
efficiency of working with integers

Quote:
Originally Posted by Larry Barello
Can you explain why not promoting to integer is more efficient? Or does that impact run time calculations even though the target may be a char?
At its heart, it's an 8 bit chip. To do arithmetic on more than 8 bits the compiler has to generate a sequence of operations, manage the carry bit, and so on. That's why working with 8 bit values is more efficient if what you're doing can fit in 8 bits.

As for declared initial values (called implicit initialization in an earlier post) - see next post.

Bill
  #6   Spotlight this post!  
Unread 21-01-2004, 11:11
WizardOfAz's Avatar
WizardOfAz WizardOfAz is offline
Lead Mentor
AKA: Bill Bennett
FRC #1011 (CRUSH)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Tucson, AZ
Posts: 101
WizardOfAz will become famous soon enough
Send a message via AIM to WizardOfAz
declared initial values (aka implicit initialization)

Quote:
Originally Posted by Mike Betts
You are doing an implicit initialization. Never a good idea in an embedded system.

Make it:

int InitFoo;

for your declaration and then

InitFoo = (100 * 5);

in your initialization routine.
I guess I'm going to disagree about the "never a good idea" comment. If the environment supports initialization, then the provided initialization mechanism will likely be more efficient (faster and smaller) than doing the initialization in your own initialization code.

I started wondering how C18 and the FRC runtime environment was handling this issue, since ANSI C both supports initialization and specifies that unitialized static data is set to zero. Here's what I found. If I've got it wrong, somebody tell me.

First, C18 ships with three versions of startup code:
c018.o which does no initialization of data and is onlyl about 1k bytes big
co18i.o which initializes static data to declared initial values, about 4k bytes
co18z.o which initializes static data to declared initial values, and zeros the rest of the static data, also about 4k bytes

Which one you use is determined by your linker script.

When you look there, you'll see that none of them are used if you're using the linker script shipped with IFI default code. Instead, the project includes ifi_startup.c, which in fact is mostly assembler embedded in a C source file. This file has the startup code, and you'll see that it does both clear memory to zero and also copy initialized data to ram. It does these both with block copies so the code is very tiny.

So at least in our FRC and EDURC environments, you can be assured that static declarations (data declared outside of a function) like this
int foo = 10;
int bar;

will result in foo being initially 10 and bar being initially zero. This initialization is done only once at power-on-reset, not each time the function is called.

If these declaration are inside a function, they are not static data. If they have declared initial values, the compiler generates code to store the initial value each time the function is called; If they have no initial value, then there is none. This is non-static data and the C18 compiler does nothing to make its value predictable. This does not violate the ANSI standard.
so in

int foobar() {
int foo = 10;
int bar;
...
}

foo will be set to 10 every time foobar is called, but bar will have no predictable initial value.

Bottom line is that this environment does initialization according to the standard. As long as you understand how static and non-static initialization differ, it's safe to use.

Bill
  #7   Spotlight this post!  
Unread 21-01-2004, 12:29
deltacoder1020's Avatar
deltacoder1020 deltacoder1020 is offline
Computer Guy
AKA: Dav
#1020 (The Indiana Prank Monkeys)
Team Role: Programmer
 
Join Date: Jan 2004
Location: Muncie, Indiana
Posts: 340
deltacoder1020 has a spectacular aura aboutdeltacoder1020 has a spectacular aura about
Send a message via AIM to deltacoder1020
Re: efficiency of working with integers

Quote:
Originally Posted by WizardOfAz
At its heart, it's an 8 bit chip. To do arithmetic on more than 8 bits the compiler has to generate a sequence of operations, manage the carry bit, and so on. That's why working with 8 bit values is more efficient if what you're doing can fit in 8 bits.
exactly - a char-char ADD op is a single instruction, whereas an int-int add requires two (and that's assuming the second ADD op automatically utilizes the set carry bit).
__________________
Team 1020, the Indiana Prank Monkeys (www.team1020.org)
  #8   Spotlight this post!  
Unread 21-01-2004, 13:43
Unsung FIRST Hero
Mike Betts Mike Betts is offline
Electrical Engineer
no team
Team Role: Engineer
 
Join Date: Dec 2001
Rookie Year: 1995
Location: Homosassa, FL
Posts: 1,442
Mike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond repute
Re: declared initial values (aka implicit initialization)

Quote:
Originally Posted by WizardOfAz
I guess I'm going to disagree about the "never a good idea" comment. If the environment supports initialization, then the provided initialization mechanism will likely be more efficient (faster and smaller) than doing the initialization in your own initialization code.
Wiz,

I guess I'm just too conservative. I have worked with a lot of processors in a lot of environments in multiple languages. I never trust the compiler options in areas like these.

If you have ever spent a week of sleepless nights rewriting code to be explicit rather than implicit because the new compiler (or even version of the compiler) does not compile like the old one did, you would be as gun shy as me.

Other things I do not do:
1. Depend on variable promotion. I use explicit casts.
2. Depend on the parser to determine order of operations. I use parentheses (a lot).
3. Use library functions. I'd rather write my own.

And the list goes on... It is a work ethic which may cost me a little more time in front of the keyboard, but my code is much more portable across multiple platforms.

As far as speed and efficiency goes, I guess I'd be using assembler if the speed of initialization affected performance critically.

Bottom line...

If everyone took as much time and effort as you have to insure which linker and compiler options gave you reliable results, this thread, and my advice, would be moot.

Most people (especially those new to programming and in the heat of a robot build) do not. As such, my advise in the future will likely be the same as my advise in the past.

Regards,
__________________
Mike Betts

Alumnus, Team 3518, Panthrobots, 2011
Alumnus, Team 177, Bobcat Robotics, 1995 - 2010
LRI, Connecticut Regional, 2007-2010
LRI, WPI Regional, 2009 - 2010
RI, South Florida Regional, 2012 - 2013

As easy as 355/113...
  #9   Spotlight this post!  
Unread 21-01-2004, 15:41
WizardOfAz's Avatar
WizardOfAz WizardOfAz is offline
Lead Mentor
AKA: Bill Bennett
FRC #1011 (CRUSH)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Tucson, AZ
Posts: 101
WizardOfAz will become famous soon enough
Send a message via AIM to WizardOfAz
Re: declared initial values (aka implicit initialization)

Quote:
Originally Posted by Mike Betts
I guess I'm just too conservative. I have worked with a lot of processors in a lot of environments in multiple languages. I never trust the compiler options in areas like these.

If you have ever spent a week of sleepless nights rewriting code to be explicit rather than implicit because the new compiler (or even version of the compiler) does not compile like the old one did, you would be as gun shy as me.

Other things I do not do:
1. Depend on variable promotion. I use explicit casts.
2. Depend on the parser to determine order of operations. I use parentheses (a lot).
3. Use library functions. I'd rather write my own.

And the list goes on... It is a work ethic which may cost me a little more time in front of the keyboard, but my code is much more portable across multiple platforms.

As far as speed and efficiency goes, I guess I'd be using assembler if the speed of initialization affected performance critically.

Bottom line...

If everyone took as much time and effort as you have to insure which linker and compiler options gave you reliable results, this thread, and my advice, would be moot.

Most people (especially those new to programming and in the heat of a robot build) do not. As such, my advise in the future will likely be the same as my advise in the past.

Regards,
Hi Mike,
Well, nobody that knows me has ever attributed conservitism to me... [;-)

Your discipline is commendable and your advice is good. I didn't mean to infer otherwise. I tend to like to get to know tools intimately and exploit them. But I understand about not becoming dependant on features that are likely to be unavailable in other environments, and that point's well taken.

In this case, I appreciate that the compiler, linker, and runtime guys made the effort to conform to the ANSI standard, and I'll make use of their work.

Best luck to your team, and may you not be haunted by the curse of un-initialized counters and wild pointers.

Bill
  #10   Spotlight this post!  
Unread 21-01-2004, 16:05
Unsung FIRST Hero
Mike Betts Mike Betts is offline
Electrical Engineer
no team
Team Role: Engineer
 
Join Date: Dec 2001
Rookie Year: 1995
Location: Homosassa, FL
Posts: 1,442
Mike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond reputeMike Betts has a reputation beyond repute
Re: declared initial values (aka implicit initialization)

Quote:
Originally Posted by WizardOfAz
Hi Mike,
Best luck to your team, and may you not be haunted by the curse of un-initialized counters and wild pointers.
Bill,

And may your bit bucket be empty...

Mike
__________________
Mike Betts

Alumnus, Team 3518, Panthrobots, 2011
Alumnus, Team 177, Bobcat Robotics, 1995 - 2010
LRI, Connecticut Regional, 2007-2010
LRI, WPI Regional, 2009 - 2010
RI, South Florida Regional, 2012 - 2013

As easy as 355/113...
  #11   Spotlight this post!  
Unread 21-01-2004, 17:19
Guest
 
Posts: n/a
Re: declared initial values (aka implicit initialization)

Quote:
Originally Posted by Mike Betts
I guess I'd be using assembler if the speed of initialization affected performance critically.
I'm assuming that writing inline assembly for the robot controller is legal, no?
  #12   Spotlight this post!  
Unread 21-01-2004, 17:35
Mark McLeod's Avatar
Mark McLeod Mark McLeod is online now
Just Itinerant
AKA: Hey dad...Father...MARK
FRC #0358 (Robotic Eagles)
Team Role: Engineer
 
Join Date: Mar 2003
Rookie Year: 2002
Location: Hauppauge, Long Island, NY
Posts: 8,854
Mark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond reputeMark McLeod has a reputation beyond repute
Re: declared initial values (aka implicit initialization)

Quote:
Originally Posted by SilverStar
I'm assuming that writing inline assembly for the robot controller is legal, no?
Yes it's legal and profitable too!
__________________
"Rationality is our distinguishing characteristic - it's what sets us apart from the beasts." - Aristotle
  #13   Spotlight this post!  
Unread 26-01-2004, 22:15
Guest
 
Posts: n/a
Re: Whacky C Complier behavior

It only assumes constants are 'chars' if they are from 0 to 255. Bigger constants are fine. You can use a quick macro to fix this:

http://nrg.chaosnet.org/repository/viewcode?id=16
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Broken PBASIC 2.5 Complier? Mike Yan Programming 12 01-02-2003 09:11
Selecting Autonomous Behavior Gobiner Programming 5 22-01-2003 09:44


All times are GMT -5. The time now is 19:57.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi