inline 函数

wiki上定义内联函数:

计算机科学中,内联函数(有时称作在线函数编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的对较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要非常注意的是对递归函数的内联扩展可能带来部分编译器的无穷编译。

 

http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Inline.html#Inline

上写道

 

 

5.33 An Inline Function is As Fast As a Macro

By declaring a function inline, you can direct GCC to integrate that function's code into the code for its callers. This makes execution faster by eliminating the function-call overhead; in addition, if any of the actual argument values are constant, their known values may permit simplifications at compile time so that not all of the inline function's code needs to be included. The effect on code size is less predictable; object code may be larger or smaller with function inlining, depending on the particular case. Inlining of functions is an optimization and it really “works” only in optimizing compilation. If you don't use -O, no function is really inline.

Inline functions are included in the ISO C99 standard, but there are currently substantial differences between what GCC implements and what the ISO C99 standard requires.

To declare a function inline, use the inline keyword in its declaration, like this:

     inline int
     inc (int *a)
     {
       (*a)++;
     }

(If you are writing a header file to be included in ISO C programs, write __inline__ instead of inline. See Alternate Keywords.) You can also make all “simple enough” functions inline with the option -finline-functions.

Note that certain usages in a function definition can make it unsuitable for inline substitution. Among these usages are: use of varargs, use of alloca, use of variable sized data types (see Variable Length), use of computed goto (see Labels as Values), use of nonlocal goto, and nested functions (see Nested Functions). Using -Winline will warn when a function markedinline could not be substituted, and will give the reason for the failure.

Note that in C and Objective-C, unlike C++, the inline keyword does not affect the linkage of the function.

GCC automatically inlines member functions defined within the class body of C++ programs even if they are not explicitly declared inline. (You can override this with -fno-default-inline; see Options Controlling C++ Dialect.)

When a function is both inline and static, if all calls to the function are integrated into the caller, and the function's address is never used, then the function's own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function, unless you specify the option -fkeep-inline-functions. Some calls cannot be integrated for various reasons (in particular, calls that precede the function's definition cannot be integrated, and neither can recursive calls within the definition). If there is a nonintegrated call, then the function is compiled to assembler code as usual. The function must also be compiled as usual if the program refers to its address, because that can't be inlined.

When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.

If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.

This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file will cause most calls to the function to be inlined. If any uses of the function remain, they will refer to the single copy in the library.

Since GCC eventually will implement ISO C99 semantics for inline functions, it is best to use static inline only to guarantee compatibility. (The existing semantics will remain available when -std=gnu89 is specified, but eventually the default will be-std=gnu99 and that will implement the C99 semantics, though it does not do so yet.)

GCC does not inline any functions when not optimizing unless you specify the `always_inline' attribute for the function, like this:

     /* Prototype.  */
     inline void foo (const char) __attribute__((always_inline));
网上找的资料:
extern inline表示该函数是已声明过的了.由于函数本身可以声明多次,所以extern对函数的影响仅仅把函数的隐藏属性显式化了.
extern 对于非函数的对象是有用的,因为对象声明时会带来内存的分配,而用 extern就表示该对象已经声明过了,不用再分配内存.
static是以前C的用法.目的是让该关键字标识的函数只在本地文件可见,同一个程序的其它文件是不可见该函数的.换句话说,就算
你其它文件里包含了同名同参数表的函数定义的话,也是不会引起函数重复定义的错误的.因为static是仅在当前文件可见.

 关于inline函数,你说的大部分的都 是对的.我来给你总结一下吧.
  inline函数仅仅是一个建议,对编译器的建议,所以最后能否真正内联,看编译器的意思,它如果认为你的函数不复杂,能在调用点展
开,就会真正内联,并不是说声明了内联就会内联,你声明内联只是一个建议而已.
  其次,因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然,就成了非内联函数的调用了.所以,这要求
你的每个调用了内联函数的文件都出现了该内联函数的定义,因此,将内联函数放在头文件里实现是合适的,省却你为每个文件实现
一次的麻烦.而你所以声明跟定义要一致,其实是指,如果你在每个文件里都实现一次该内联函数的话,那么,你最好保证每个定义都
是一样的,否则,将会引起未定义的行为,即是说,如果不是每个文件里的定义都一样,那么,编译器展开的是哪一个,那要看具体的编译
器而定.所以,最好将内联函数定义放在头文件中.
  而类中的成员函数缺省都是内联的,如果你在类定义时就在类内给出函数,那当然最好.如果你在类中未给出成员函数定义,而你又想
内联该函数的话,那在类外要加上inline,否则就认为不是内联的.而且刚说了,内联函数最好放在头文件内,所以最好在类定义的头文件
里把类的内联函数都实现了.
  而你说的将声明与实现分开,其实是不会编译出错的,反正我写那么多程序都没试过.将声明与定义分开的话,这样的后果会带来编译
器并不随处可见该函数定义,所以,只能在你实现定义的那个文件里,将该函数看成内联(如果可以内联的话),在其它文件,仍看成是普通函数.
先假设你的函数符合内联的条件.
  在声明是加inline,定义时不加,则要求编译器编译时,能看到inline的声明,而且在展开点看到该定义,这样,就将其视为内联函数.
  如果你声明没有inline,却在定义时inline了.这时,如果其它要调用该函数的文件看到了它的声明,就认为该函数不是内联的,所以,
到了调用处,转到该函数实现的地方,却意外地看到了inline声明,这时,会导致链接出错.若要改正的话,就要让调用该函数的文件也
看到有inline的定义,而不是在调用时才看到.你可以在每个文件都加上有inline的定义.(如果不加inline,则会出现重复定义的错误,
因为内联函数才可以被重复定义).或者另一种修改方法,你将定义时的inline去掉,这样就成为普通函数,链接不会出错.如果是前一
种改法,仍是内联的,因为符合了看到了inline且随处可见其定义的条件.
如果你将声明跟定义都放在同一个头文件,而在声明时不内联,在实现时内联,这样编译器也是将该函数内联(符合两个条件,看到inli
ne的声明(虽然是在定义时),随处可见其定义).
  总结说来,只要编译器看到有inline出现,而且定义随处可见,就能将函数内联(上边已假设你的函数足够简单可以内联),而不必管是
定义还是声明加inline的问题.
  所以,为了方便,将内联函数直接声明时就定义,放在头文件中.这样其它文件包含了该头文件,就在每个文件都出现了内联函数的定
义.就可以内联了.
  类的成员函数也一样.只不过,类的成员函数缺省都是内联的,前提是你要在类定义时提供成员函数定义.如果在类定义时不提供函
数定义,则要在类外边加上inline,否则将视为普通函数.
这是逼我看C++ primer啊。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值