by Nigel Jones
原文:http://embeddedgurus.com/stack-overflow/2008/12/efficient-c-tips-5-make-local-functions-static/
In my humble opinion, one of the biggest mistakes the designers of the ‘C’ language made, was to make the scope of all functions global by default. In other words, whenever you write a function in ‘C’, by default any other function in the entire application may call it. To prevent this from happening, you can declare a function as static, thus limiting its scope to typically the module it resides in. Thus a typical declaration looks like this:
static void function_foo(int a) { }
Now I’d like to think that the benefits of doing this to code stability are so obvious that everyone would do it as a matter of course. Alas, my experience is that those of us that do this are in a minority. Thus in an effort to persuade more of you to do this, I’d like to give you another reason – it can lead to much more efficient code. To illustrate how this comes about, let’s consider a module called adc.c This module contains a number of public functions (i.e. functions designed to be called by the outside world), together with a number of functions that are intended to be called only by functions within adc.c. Our module might look something like this:
void adc_Process(void) { ... fna(); ... fnb(3); } ... void fna(void) { ... } void fnb(uint8_t foo) { ... }
At compile time, the compiler will treat fna() and fnb() like any other function. Furthermore, the linker may link them ‘miles’ away from adc_Process(). However, if you declare fna() and fnb() as ‘static’, then something magical happens. The code would now look like this:
static void fna(void); static void fnb(uint8_t foo); void adc_Process(void) { ... fna(); ... fnb(3); } ... static void fna(void) { ... } static void fnb(uint8_t foo) { ... }
In this case, the compiler will know all the possible callers of fna() and fnb(). With this information to hand, the compiler / linker will potentially do all of the following:
- Inline the functions, thus avoiding the overhead of a function call.
- Locate the static functions close to the callers such that a ‘short’ call or jump may be performed rather than a ‘long’ call or jump.
- Look at registers used by the local functions and thus only stack the required scratch registers rather than stacking all of the registers required by the compiler’s calling convention.
Together these can add up to a significant reduction in code size and a commensurate increase in execution speed.
Thus making all non public functions not only makes for better code quality, it also leads to more compact and faster code. A true win-win situation! Thus if you are not already doing this religiously, I suggest you go through your code and do it now. I guarantee you’ll be very pleased with the results.
// 评论也精彩.