Hello ! I have a problem which I can't resolve. I wrote program for 89C2051 for one of my friend in Basom Basic compiler (http://www.mcselec.com). Compiled code was about 1945 bytes. Since I prefer C, I transalte Bascom basic to C. But when I compile, generated code was 2313. I try to change optimization parameters, but generated code never go below 2313. Even bigger. Where am I wrong ? Is it possible that stupid Basic make smaller code tne best C compiler ? Then I find out that this code: while (1) { printf ("Hello World\n"); } generate fully 1093 bytes (!) for Atmel 89C2051. 1093 bytes???? Three lines? Same program in Bascom generate only 154 (!) bytes. When I remove all "printf" from my C code, generated code was arond 2200 byte. But, with same action in Basic code (remove all "print") 1340 bytes long code. Exactly same program in Keil C and Bascom basic generate 860 byte smaller code ! I don't belive this. Do I have to program in (stupid) Basic if I want smaller code ? I still belive I did mistake somewhere, so I need help. I will send both C and basic code for interested people. With best regards !
printf() in C is a much more powerful command than PRINT in BASIC. Try changing printf ("Hello World\n"); to puts("Hello World"); and your program size will fall dramatically. Moral, don't use printf() if you don't need to.
1417 ! Hey dude, that's what all call good advice ! If you know more tricks like this .... Thank you !
To reduce program size, you have to stop and think what you are asking the compiler to do. When you used printf(), you forced the compiler to include all the library code for the formatting options that printf() supports. That is why puts() is better if you don't need formatting, because it is dumb. BASIC PRINT is small because it is a simple command. You call the USING function in BASIC to help format outputm which your example didn't do. Secret number 2 is, ask the compiler to output an assembly language listing, and have a look at how much code it is generating for each function. Try varying how you write your code, to see what effect it has on the generated output. Sometimes multiple simple statement give better code than complex statements. e.g. I found that
temp = buffer[ptr++]; var1 = temp; var2 = temp;
var1 = var2 = buffer[ptr++];
One thing you miss in your comparison is the fact that some 'program builders' (I avoid 'compiler' since basic is not) rely on you needing some features that you WILL need when you go beyond "Hello World". It is usually the case with efficiency comparisons that the best will fail miserably with very small programs. Erik
erik said "(I avoid 'compiler' since basic is not)". Don't you think "BASCOM" is a contraction of "BASic COMpiler"? Yes, most traditional BASIC's were interpreted, but if BASCOM was producing a complete program in 152 bytes, with no extra support files needed, then it must be compiling.
Many C compilers will supply you with multiple versions of printf(). They snoop the format string to find out which features you actually use, and then link in the minimal printf() that supports the features you need. So, if you only use %x and %u and literals, you get a tiny little printf, and if you insist on using floating point engineering notation with right-justified in field widths specified by a parameter, well, then, you get a bigger printf() linked in.
"Many C compilers will supply you with multiple versions of printf(). They snoop the format string..." Over to Keil (Jon?): does C51 do this? My suspicion is, it doesn't - but then I don't remember using one that did!
Over to Keil (Jon?): does C51 do this? Nope. Keil C51 has two versions of printf. A version that supports everything but floating-point and a version that supports everything including floating-point. The problem with snooping the format string at compile time is that the format string is not required to be constant. I think that a constant format string would be required in order to do this. If the program dynamically built the format string based on the types of data stored in a database, then how would the compiler be able to snoop the string. Or, what if the format string was received over the serial port. How would the compiler know which printf to link in? As far as I know, there are several compilers that do include reduced capability printf functions. I seem to recall that IAR and maybe even Tasking did this. It used to be that most experienced developers used printf and scanf for testing but never in final applications. In many applications sprintf is used to format strings that are subsequently sent to some kind of buffered serial output function (or maybe puts). However, in many of the embedded systems I've worked on, the data types were fairly unique and each had their own output format function (because this generated less code than printf or sprintf). Jon
The method how to handle non-constant format strings is obvious, isn't it? *) Start out with the minimal-feature version *) Every time you see a constant format string being used that requires a feature not supported by the currently selected version, elevate to the first that does. *) The first time a non-constant format string is seen in a compile, optionally output a performance warning, and switch to the maximal version.
This is getting kind of silly. If anyone uses Printf for anything but debug, they are writing "PC code". If "PC code" is employed all bets regarding code size is off as should be by Mr. Gates decree. C51 and its cousins are thankfully optimized for "embedded code" which is what the '51 and derivatives are intended for. Erik
I faced a problem of having a project which had to include some 'reference code' that could not be changed. Of course, it was full of printf() statements. My solution was to write my own printf() function that included just the required features. This also gave me the opportunity to add in some non-standard features that I found very useful and further reduced overall code size. My user_printf() function is a bit big to post, but if you want a copy I can e-mail it. Please post your e-mail address if you are interested.
"This is getting kind of silly." You're telling me. "If anyone uses Printf for anything but debug, they are writing "PC code"." Actually, a lot of us are using printf() or sprintf() in our embedded firmware - if you have a lot of formatting to do it would be stupid to do anything else. If there is enough code space to use it for debugging, why not use it for release code? "If "PC code" is employed all bets regarding code size is off as should be by Mr. Gates decree." printf() rather predates Microsoft's grip on the world. "C51 and its cousins are thankfully optimized for "embedded code" which is what the '51 and derivatives are intended for." Indeed, but when the 8051 wants to communicate through its little window on the world it may need to do so in a format the user can understand. That's where printf() comes in. Don't tell me you're a subscriber to the 'Real men code in assembly, C is for boys' philosophy? Maybe it's time to drag yourself into the 21st century. Stefan
"I faced a problem of having a project which had to include some 'reference code' that could not be changed. Of course, it was full of printf() statements. My solution was to write my own printf() function that included just the required features." I'm curious about this - if you replace the library printf() calls with your own version of printf() you have modified your reference code. Stefan
Indeed, but when the 8051 wants to communicate through its little window on the world it may need to do so in a format the user can understand. That's where printf() comes in. NO communication to "the real world" need be that complicated, if it is the maybe some post-processing at the receiving end would be an idea. Don't tell me you're a subscriber to the 'Real men code in assembly, C is for boys' philosophy? No, I am not; however I do belong to the "the '51 is not a PC club" Erik
Hello ! My first intention was to find someone to help. You are going in oposite direction. After all this posts you make, I see that I can use both printf and pust. It only how much code I have in microcontroler. since I used AT89C8021 it was painful to spend 1 Kb. But, when I use some bigger (8252) maybe I will use printf. As long as I have enough code. Best regards ! P.S. what is best, I found perfect place for resolving some problems, since I am new in C for embeded applications. Thanks again.