Efficient C Tips #5 – Make ‘local’ functions ‘static’

50 篇文章 1 订阅

  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.

    // 评论也精彩. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值