![]() |
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. |
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. |
Re: Whacky C Complier behavior
Quote:
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 |
Re: Whacky C Complier behavior
Quote:
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. |
efficiency of working with integers
Quote:
As for declared initial values (called implicit initialization in an earlier post) - see next post. Bill |
declared initial values (aka implicit initialization)
Quote:
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 |
Re: efficiency of working with integers
Quote:
|
Re: declared initial values (aka implicit initialization)
Quote:
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, |
Re: declared initial values (aka implicit initialization)
Quote:
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 |
Re: declared initial values (aka implicit initialization)
Quote:
And may your bit bucket be empty... Mike |
Re: declared initial values (aka implicit initialization)
Quote:
|
Re: declared initial values (aka implicit initialization)
Quote:
|
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 |
| All times are GMT -5. The time now is 00:35. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi