Pre-Processers for Inlined C Code? 62
Scott Snell asks: "I have inherited the C code for an embedded system project that has run out of code space. The source code is highly fragmented and the compiler doesnt generate efficient code for stack handling. Ideally I would direct the compiler to 'inline' a lot of the functions but unfortunately it doesnt support the inline keyword. Using macros is dangerous and manually inlining is driving me crazy! What I need is a tool that will take the source files, look for the 'inline' keyword and generate new source files that are inlined. Any ideas?"
Port it. (Score:3, Insightful)
Regards, Guspaz.
Re:Port it. (Score:5, Informative)
I have inherited the C code for an embedded system
There's a good chance that the compiler this person is using is the only one that's available for the architecture in question. I mean, he could be talking about a microwave oven or a car ignition system or something.
Re:Port it. (Score:3, Interesting)
Re:Port it. (Score:2)
in a word... (Score:2, Funny)
Re:in a word... (Score:2, Redundant)
Here Here!
Perl would be excellent for this job.
Re:in a word... (Score:2)
And a hearty fuck you to whoever modded me redundant. No shit it's redundant, the point of the post is to bolset the opinion of the parent post. Multiple voices speak stronger than one. Redundant would be if two people both cut-n-pasted an article text or something like that.
Re:in a word... (Score:2, Funny)
Use macros (Score:3, Interesting)
Unless I'm on crack, inlining all calls to a function is pretty much the same as replacing the function with a macro. The main difference between inlining and macros would be that the compiler can decide not to inline a function if it doesn't make sense (e.g., if the function is recursive and the compiler isn't up to iterative-izing it), whereas with macros you just can't do recursion safely.
Re:Use macros (Score:4, Insightful)
Macros are simply 'cut-n-pasted' into the source, then compiled. Thus, no type checking takes place.
There are many reasons you should try not to use macros. Personally, I try to avoid any preprocessing when I can. The C++ FAQ Lite [parashift.com] is much better at explaining it all that I. More specifcially, try Reason 1 [parashift.com] Reason 2 [parashift.com] Reason 3 [parashift.com] Reason 4 [parashift.com]
Yabbut... (Score:2)
Re:Use macros (Score:1)
In cases where yuo put an entire function into a macro, you're not going to get a return value the way you normally do, most likely you'll pass the variable that will hold the return value as an argument. which in that case, since the preprocessing is done BEFORE the compiler ever sees the code, so it really is inlined in the truest sense of the word. And type checking is done just the same as with 'normal' code, because it IS normal code once the compiler gets the preprocessed code.
say like: is EXACTLY like: so where did the lack of type checking come from?
Re:Use macros (Score:1)
Re:Use macros (Score:1)
Re:Use macros (Score:1)
Re:Use macros (Score:1)
Re:Use macros (Score:2)
The lack of type checking comes from:
blah('1', "Stromsmoe", 2.14159)
Re:Use macros (Score:1)
Inlining (Score:1)
Re:Use macros (Score:1)
Re:Use macros (Score:2)
Yes, I failed to think about general macro lossage the first time around. I'm still going to claim that it's the sanest way of doing without inlines, since I've never seen a preprocessor that will inline __inline__ functions for you, and writing your own is unlikely to be worth the trouble. Go ahead and use macros, just beware of the pitfalls.
GCC? (Score:1, Interesting)
inline will make your code *bigger* (Score:5, Informative)
What compiler is being used? The inline keyword is not supported by ANSI C - it is a C++ feature. However many C compilers support a proprietary inline declaration. Examples:
Green Hills: __inline
Diab: __inline__
Others use: #pragma inline
So, RTFM. Also, check the docs for inlining optimizations.
Jeff
You're right, but... (Score:5, Insightful)
On the other hand, I reread the post several times, and I'm probably wrong, but it almost sounds like he is running into a problem with "source code" space. Could it be that he is compiling the code on the embedded system?
At any rate, this post should be modded as Offtopic because it doesn't really attempt to answer the problem. I'm guess I'm just trying to figure out if there isn't maybe another solution.
Re:inline will make your code *bigger* (Score:2)
Re:inline will make your code *bigger* (Score:4, Informative)
Inline is in C99, see section 6.7.4 of the standard.
That said, inlining can reduce code size if the function body object code is small relative to the parameter setup object code. Absent an inline feature in the compiler (what compiler could that be?), I think macros would be less dangerous than any specialized "inline preprocessor", even if there should be one.
Perhaps Embedded C++ (Score:2, Interesting)
Green Hills [ghs.com] has proposed an Embedded C++ standard [ghs.com] which is essentially ANSI C++ without exception handling, mutiple inheritance, namespaces, run time type identification, templates, or virtual base classes. It does support the C++ inline keyword. So the compiler will, when possible, expand functions as macros. This results in faster performance at the expense of larger code space, but smaller stack space.
There are few problems porting code from C to C++. It's actually more difficult to port from pre- to post-ANSI C++, e.g. because of changes to the definition of the for statement. A C++ compiler is more type strict then a C compiler, meaning that more operations between different fundamental data types will be flagged as errors.
EC++ won't result in tremendous code bloat, either. About the same order of ANSI C. Plus if this system continues to evolve, one can take advantage of easier memory allocation with new and delete as opposed to malloc and free.
Granted the original post asked about inlining C functions. But moving to C++ gives one portability, since the inline keyword is part of the ANSI C++ standard.
Macros aren't necessarily as dangerous... (Score:5, Insightful)
Macros have their dangers, but at least their dangers are well understood, and should be familiar to anyone who is writing embedded C. It is the commonly used solution to your problem, which makes it nice for keeping your code maintainable.
If you use a trick to get around the problem, it will just be another thing to confuse the next person who has to maintain the code.
Various... (Score:2, Informative)
foo = bar(i++);
and you'd better hope that the parameter isn't used more than once in the function's code - otherwise i will get incremented too often - hello bugs!
Flip side, you can eyeball the most commonly used functions for safe-to-macro-inline candidates and save space just on them.
An el-crapo compiler could easily burn more bytes with call & return code than a small function would need inline.
Are there any dusty & old or not-so-essential hunks of this code that could be ditched? A badly-written section that could be rewritten much smaller? Wordy user interface stuff to edit down?
Re:Various... (Score:1)
IIRC, the first example should be optimized up the waazoo. loop goes away (duh), and it's possible, depending what you're doing with v, that v will vanish.
Complete Solution Available (Score:5, Interesting)
Their preprocessor happens also to be a complete C++ compiler. You don't have to use the rest of the C++ features. (You might, for example, want to turn off exception handling.)
Any half-assed preprocessor that just folds function bodies into line is likely to be much worse than using macros. The worst possible outcome is code that's in some weird private language that only your weird private tools understand. (Cf. Qt/KDE)
Re:Complete Solution Available (Score:2)
#include (Score:2)
Re:#include (Score:1)
If you're going to do it, you might as well use #define. It will have the same effect, but its a more standard way to say it. (and you don't have to have a bunch of files with just one function)
Re:#include (Score:2)
have macro expansions in the included text without
re-#defining the whole function body.
As for parameters, do
#define PARAM1 abc
#define PARAM2 def
#include "function.i"
#undef PARAM1
#undef PARAM2
Use a macro processor, just not the C preprocessor (Score:5, Informative)
Inlining probably won't help (Score:2, Redundant)
I'd actually be inclined to go the other direction- is it possible to uninline things? If the code is doing similiar things in different places, is it possible to write a single function which is instead called in both places?
Barring that, other options include using a different complier- does gcc support your processor? I know gcc doesn't support everything under the sun- many 8- and 16-bit micros and DSPs aren't supported, for example. But if gcc is supported, it does pretty good on the stack space management and automatically inlining. Or you just might have to bite the bullet and spring for a larger rom/flash or larger cpu.
Brian
Self-service (Score:2)
http://manju.cs.berkeley.edu/cil/cil001.html
"Dear Slashdot" (Score:5, Insightful)
I think the problem can be solved by inlining functions. Yes, inlining. Even though this generally increases code size, I think it's the solution in this case. You don't have enough information to argue about this, so trust me. Just give me a solution. Can you write me a Perl program, for example? I told you that the word you are looking for is "inline". Is there anything else you need to know?
Macros are dangerous? (Score:2)
Using macros is dangerous and manually inlining is driving me crazy! What I need is a tool that will take the source files, look for the 'inline' keyword and generate new source files that are inlined.
Umm, isn't looking for the inline keyword and generating new source files dangerous as well?
AWK! (Score:2)
Why? So you can con management into buying you that nifty O-reilly CD-ROM series for UNIX!
Worked for me...
stack handling? (Score:1)
Must be a VERY old C Compiler (Score:2, Insightful)
That said, you are looking to refactor your software anyway, you might as well do it right, possibly starting with picking a newer more modern toolset, architecting the code differently to allow you to optimize for stack/code/data space, and many other factors. Will this take time, of course, but it might not take as long as a simple little hack, plus give you better results, and the ability to improve in the future. Will management buy it ??? Probably not, so just tell them you are inlining everything, and give them so much more out the back end.
are you kidding? (Score:5, Informative)
Stack space? Inlining is not neccessarily going to solve this problem. Recursion is probably your problem. Also, make the stack larger if possible.
Instruction space? Inlining will most likely make this worse, except in extremely abstracted code where the overhead to make the function call is more than the inline expense.
The solution is to fix the compiler's stack handling. When the compiler is the problem, fix the compiler. I've never heard of an embedded systems project that didn't include someone hacking with the compiler.
Ideally I would direct the compiler to 'inline' a lot of the functions but unfortunately it doesnt support the inline keyword.
Changing the compiler to support the keyword is probably a pain in the butt. However, there are very few C compilers which don't support some form of the inline keyword. Double check your docs.
Using macros is dangerous...
Macros Dangerous? That's rediculous. I suppose creating some wierd perl script to munch through your source code ripping up inline functions and auto-generating C files that will never have the propper dependecies is safe?
This is crazy! Autogenerating code is a great way to totally fuck up your build system. You'll never get your dependencies right and you'll end up building your entire project every time. Writing a tool that will parse your source code and identify the inline keyword is *exactly* as complicated as making the compiler understand the inline keyword. Don't do some bizzare on-off wierd hack. Instead, if you really want to use inline, bust out your compiler source and get cranking. If you don't have the compiler source, bust out gcc source and get cranking porting gcc to your hardware.
On another note... (Score:2, Funny)
Re:On another note... (Score:1)
There are lexer and parser generators (e.g. flex and bison) that take a context-free simplification of the language and automatically produce efficient and bug-free lexers and parsers. But you have to take care of the context-sensitive part of the language (e.g. checking that variables are declared before they are used) and the code generation manually.
Re:On another note... (Score:1)
Think about it. If such a thing were possible, why would compiler writers waste all their time doing it manually?
Actually, I really am a compiler writer, and yes, I do know that such a thing is, of course, impossible. And that was part of the joke in the post you replied to. Asking for the impossible, or nearly impossible. Sort of like request in the story: "Can you give me a link to the nearly impossible? If not, can someone do it for me?" Also, please note the ellipsis at the end of the post. That tends to denote a lack of seriousness in a post that is a series of requests.
cfront (Score:1)
The cause: Out of memory. The solution: ... (Score:1)
hacking or planing? (Score:1)
You are talking about inline, stack, hacking,
I think you have to think about your code functionality, and than you will be able to see how you can fix this problem witout any hacking. There is always a way to fix the real problem!
What you are trying to make is cover a bug with another bigger one! Dont be crazy!!
What you should do is planning and not hacking!