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 mr. Graham Cole ! Please send me your custom print() function. And some explanation how to install it and use. With regards ! Mladen Bruck
I will need your e-mail address.
Ops ;) mladen.bruck@pincom.net
So the fact that the 8051 is not a PC means that if you do use a (relatively) high level language such as 'C' relatively high? what about efficient. Because it somehow isn't proper? The next we will see is "just add a megabyte of ROM and you can do the proper thing and use C++" Erik
"relatively high? what about efficient" 'C' is relatively efficient. What's your point? "The next we will see is "just add a megabyte of ROM and you can do the proper thing and use C++"" You already can use C++ without adding a megabyte of ROM. Perhaps you should try it? Stefan
Stefan, Nothing personal, but you come across as a "if it is too slow buy a faster (more expensive) processor, do not try to streamline the code, it may make it not proper" person. We are discussing the difference between a microcontroller and a microprocessor related to purpose, use, functionality and application. I have worked with "real C" programmers and they professed that there was no need whatsoever to understand the purpose of the equipment such as no C++ for low cost or ultrafast response. I once revised a development where a bloated RTOS with some "real C" code bugged the processor so far down that the "real C programmer" suggested a change to an ARM processor. It took about a month to get the bloatings out of the code (still using C) and then the '51 was more than sufficient. Re C++ you need to read this interview http://www.ganssle.com/tem/tem17.pdf Trevlig kvaell Erik
You can write bloated code in any language, including assembly. You can write "efficient" code in C, and yes, even in C++ -- if you know what you're doing. C++ in particular is more subtle and thus more difficult than it seems on casual inspection. The smallest overall program is not necessarily one where individual basic blocks are the smallest.
You can write bloated code in any language, including assembly. I agree; however it is a characteristic of "real programmers" as opposed to "embedded programmers" to concentrate on the elegance (in their opinion) and state of the art of the code rather than the efficiency. I consulted for a while with a major cellphone company and the "real programmers" decided to go to C++. This led to the need to double the clockspeed of the processor. Before this happened I said, wrote and almost screamed "faster clock is more battery usage and one of the problems we have is is battery charge life". They went ahead anyhow "because it is the right thing to do" and now the lack of battery life has led to a sharp decline in sales for that company. Erik
The method how to handle non-constant format strings is obvious, isn't it? Apparently, not obvious enough. The mechanism that you outline is suitable for an interpreted language, but a compiled application has to be self-sufficient. The app can not, at run time, upon encountering a foreign format specifier, ask the compiler for anything. - Dave
Dave, I can't see anything wrong with Hans's description. What he describes happens at compile time. His third point was that if the compiler sees a non-constant string anywhere in the code, then it gives up trying to optimise, and uses the full-featured version of printf().
You can get into situations where, for example, if there are multiple source files, each source module calls for a different "edition" of printf. If this is the case, it is actually up to the linker to resolve which printf gets included. It's fairly easy for the compiler to say, "Oh, this module calls printf and only has an unsigned int in the format string. OK, include printf#1." In another module, however, the compiler might say, "Oh. this module calls printf and uses floating-point format specifiers in the format string (but no unsigned ints are used). OK, include printf#4." Now, the linker has to make sense of all of these different printf functions. And, at the end of the day, the linker includes most of what's in the standard printf. The only applications this would work well for would be the Hello World example. I mean, if I include sprintf in my application, I'm going to use it to my best advantage. I'm not going to try to use a printf SUBSET to save memory. If memory is that precious, I'm going to write my own formatting routines. printf has been an acknowledged memory hog since C was invented. There have been very few successful attempts at reducing its size. For its size, I think it does quiet well. Jon
I just downloaded the BASCOM demo and played around for a while. It's pretty neat. After playing around for a while, I decided to run a real program and compare it to C51. Not wanting to spend the rest of my life on this, I chose the SIEVE. Here are the results: BASCOM: Code Size: 866 Bytes Execution Speed: 23.553726 Seconds Keil (using printf): Code Size: 1,248 Bytes Execution Speed: 6.331546 Seconds Keil (using putchar and puts): Code Size: 524 Bytes Execution Speed: 6.330123 Seconds I did all speed testing with the uVision2 Debugger/Simulator under identical circumstances. From this little comparison, I think you can tell that the printf is what kills the C code--but not the performance. And, the difference between a CUSTOM formatter (using puts and putchar) and printf saves 724 bytes. I'll be more than happy to post the source for these things (of course, the SIEVE source comes with the Keil tools) if anyone wants to check my work. Jon
And...with linker code packing... Keil (using putchar and puts and linker code packing): Code Size: 486 Bytes Execution Speed: 6.330105 Seconds Jon
Jon, Here's a suggestion for the manual. How about adding a note to the printf page, pointing out that puts/putchar use much less code memory for simple output.
Dave, I can't see anything wrong with Hans's description. What he describes happens at compile time. His third point was that if the compiler sees a non-constant string anywhere in the code, then it gives up trying to optimise, and uses the full-featured version of printf(). Hmmm.. okay, I went back and re-read the post that I (somewhat snippily) replied to, and I agree that it's technically possible. However, this feels like something that should be taken into account and compensated for (if necessary) on the application side rather than the tools side. If you start building this level of "special case" consideration into the toolset, you'll wind up with Win51, the first 32-bit (!) GUI OS for embedded 8051 applications, and I, for one, would rather skip that particular nightmare. Not to mention the extra development effort and cost and the price point impact it would no doubt have. IMHO, of course. You could also argue that this is the whole point of having an optimizer. It's late. I give up. =) - Dave
Nice job comparing SIEVE in both compilers. You now know whay I did the first post. But I didn't measere execution time. Where is the swith for linker code packing ? I make another threed post, where I looking Libraries for smart cards (eg. SLE4428). Anyoone help since this is most 'live' thread ? Mladen Bruck
"Where is the swith for linker code packing?" It's in the "Options for target" -> "C51" tab. Stefan
If tools are available that are beneficial to the project then use them. Don't rule things out merely because you've decided at some time that they are not appropriate. Stefan, You are thinking development, I am thinking end product. Using a bit of assembler I managed to change a product so that it could be manufactured for $1.83 less. That does not sound like much till I tell you that 500.000 were made. A modern C compiler can make code very close to (sometimes better than) a seasoned assembler programmer and for code that does not utilize special functions of the hardware C is, indeed, my choice. The REAL problem with C and more so with C++ is that it allow the programmer to obfusciate the code to a level where no single soul can figure out what happens. I have seen 500 character long if stetments. The worst about C is that it is stated to be "self documenting" I would rather buy swampland in Florida than attempt to read C code by someone that believes that. Stefan, I believe very much in "the right tool for the job" and my products now vary from 99% C and 1% assembler to a speed demon that is 25% C and 75% assembler. I have yet to see ANY C++ code that is maintainable and efficient. There is no way anyone is going to convince me that code that inherits and morphs is going to be more maintainable than code that does not. There is no absolute divide between controllers and processors in much the same way that there is no absolute divide between what is and is not suitable for use on each device You are right; however, if you program a microcontroller as a microprocessor and tell me that is the right thing to do, you better have some very good reason. You state about 5 levels into this discussion that you are doing the above for battery life reasons. I can accept that easily enough, but initially you stated it as a global right thing to do, which I can not agree with. Erik
Where is the swith for linker code packing? The Use LX51 Linker must be enabled as well. Jon
I use C because I can crank things out very quickly. Often in a matter of minutes. This allows me to test and prove ideas and algorithms quickly. And, with the significant reqources available (examples, forum, and so on) C on the 8051 is pretty hard to beat. I mean with google and this forum, I rarely have to post questions asking for things -- I just have to be really, really good using the search tools that are available. Once everything works (or mostly works) I can start optimizing for speed. This is where I use the profiler to figure out where most of the program's time is spent. There's no need to speed up something that's only invoked a few times. Speed-up the stuff that's invoked a thousand times. I usually start optimizing for size from the very beginning. If I know that I'm size limited, I try to figure out what is the biggest memory hog that I'll have, is it data, long term storage, constants, code, or ???? Once I know what the big memory space killer is, I work on reducing that first. Then I work my way to the second biggest, and on down the line. Jon
"There's no need to speed up something that's only invoked a few times." Unless, of course, those few times happen to be in the critical path on which the whole system depends...! Just goes to show that all generalisations are bad...! ;-)
"The REAL problem with C and more so with C++ is that it allow the programmer to obfusciate the code to a level where no single soul can figure out what happens" Oh yes - this is definitely true. However, I can't see that the same is any less true in Assembler. I think the problem here lies in the programmers - not the language?!
"The REAL problem with C and more so with C++ is that it allow the programmer to obfusciate the code to a level where no single soul can figure out what happens" Oh yes - this is definitely true. However, I can't see that the same is any less true in Assembler. I think the problem here lies in the programmers - not the language?! Of course you are right; however obfusciated assembler is a lot easier to decipher than morphed, encapsulated and whatever C++. The point I am making is that the more "abstract" the language allow you to be, the easier it is to hide what it is you are doing (just compare an abstract painting to a naturalistic). Thus a C++ programmer has to be extremely conscious of the maintainability of his/her code more so that utilizing all bells and whistles the language allow and I have yet to see C++ code written expressly for maintainability. Show me that a majority of C++ programmers are writing code expressly for maintainability (no babble about safety from encapsulation and all that other hype) and I may change my attitude about that language. Erik
"Of course you are right; however obfusciated assembler is a lot easier to decipher than morphed, encapsulated and whatever C++." Not for those of us who are used to using these new-fangled high level language things! "The point I am making is that the more "abstract" the language allow you to be, the easier it is to hide what it is you are doing" Exactly! "Thus a C++ programmer has to be extremely conscious of the maintainability of his/her code" Maintainability is one of the strong points of C++. I'd say that well written assembler is more difficult to maintain than poorly written C++. As an amusing excercise try translating a few lines of an assembler program as directly as possible into C on a line by line basis. Once you remember what a lovely and incredibly useful keyword 'goto' is you'll make progress. "Show me that a majority of C++ programmers are writing code expressly for maintainability" Of course they aren't, they're writing code to produce a working product. Maintainability is just one of the many side benefits of using C++. "(no babble about safety from encapsulation and all that other hype) and I may change my attitude about that language" You can't expect us to expalin the benefits of a language with the proviso that we ignore the features that provide the benefits! Erik, you just seem to think that your way is the only way, and you're going to hang on to it at any cost. Good luck! Stefan
"(no babble about safety from encapsulation and all that other hype) and I may change my attitude about that language" You can't expect us to explain the benefits of a language with the proviso that we ignore the features that provide the benefits! Stefan, the features babbled about serves only to hide what you are doing which hardly improves maintainability. The claim that "abstraction" improves maintainability is pure unadulterated bs. Anyhow since there are three things you can not discuss with your barber: religion, politics and taste this will lead nowhere. I offered you a way to convince me: "show me that a majority of C++ programmers write for maintainability" and insted of replying to that you babble about "automatic maintainability" which is impossible. My main objection to C++ is not the language, but the way it is treated. When assembler is taught every other sentence is "think mainatinability" when C++ is taught every other sentence is "the language takes care of that". My problem with C++ is not as much with the language as the way it is taught "everything will be better when you use C++" which is a load of compost. I once employed a C programmer who when asked to put commets in his code and break up some mile long statements answered "that is not real C". This attitude is so much more prevalent in C++ programmers. The fact that C++ provides an excuse to write unmaintainable code because it claims that it (just read your own statements) makes the code maintainable is the worst thing possible. Erik
"(no babble about safety from encapsulation ... the features babbled about serves only to hide what you are doing which hardly improves maintainability." Erik, 'encapsulation' doesn't mean hiding what you are doing. Quite the opposite - it makes clear what you are doing. "I offered you a way to convince me: "show me that a majority of C++ programmers write for maintainability" and insted of replying to that you babble about "automatic maintainability" which is impossible." I'm afraid you've imagined my use of the word 'automatic'. By the way, I wasn't babbling. "when C++ is taught every other sentence is "the language takes care of that"" No professional teacher would say that. Neither do any of my C++ books. Did your teacher say that? Ahh.. you've never been taught C++. "I once employed a C programmer who when asked to put commets in his code and break up some mile long statements answered "that is not real C"" Well, there are always a few bad eggs. I've worked with a couple of individuals who took this sort of attitude however their real intention was to, and I quote, 'keep the amateurs out'. The language used was irrelevant - nothing was commented. "The fact that C++ provides an excuse to write unmaintainable code because it claims that it (just read your own statements) makes the code maintainable is the worst thing possible." C++ doesn't provide an excuse to write unmaintainable code. It does however aid writing maintainable code. I think it is obvious (and I've never tried to suggest otherwise) that this requires some effort from the programmer. Stefan
Stefan, 1) Did you read the interview with Bjarne I posted the link to? There is the real truth. 2) I have nothing against any language when applied in the places where it belong, my hair raise when someone states that it is the right choice in all situations. 3) C++ (at least in its present form) has no place in the '51 world, if you want to use it on a PC be my guest. Erik
Erik, 1) Sure, that's been on the go for years. Bjarne claims it would have been funnier if he'd written it but I doubt that somehow. 2) Indeed. However, I feel the same way when someone states that something is the wrong choice in all situations because that is equally false. 3) I do use C++ on the PC and I don't use C++ on the 8051. However, I also use C and very rarely assembler on the PC, and I would be interested to try the C++ implementation on the 8051. Tell me, have you actually tried it? If not, have you read any report by anyone who has actually tried it? Stefan
C++ compilers are very useful for embedded design. This is true even if you write using only C constructs. The primary benefit I find is that they can help remove type errors not caught by C compilers. When selecting a language and compiler, you need to weigh the cost of the options afforded you.
View all questions in Keil forum