error C2054:在“inline”之后应输入“(

按照编译错误的提示来看应该是编译器没有识别inline参数。查阅了一下inline是c++里面的东西,在c里面使用是会发生错误。

解决办法就是将inline修改为__inline或者在mapserver.h中增加了如下的定义:

#define inline__inline

或者改为使用/TP指定源文件类型为C++。

http://blog.sina.com.cn/s/blog_4e668bc80100nnjg.html

///

C语言inline详细讲解

本文介绍了GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点:inline关键字在GCC参考文档中仅有对其使用在函数定义(Definition)上的描述,而没有提到其是否能用于函数声明(Declare)。

从inline的作用来看,其放置于函数声明中应当也是毫无作用的:inline只会影响函数在translation unit(可以简单理解为C源码文件)内的编译行为,只要超出了这个范围inline属性就没有任何作用了。所以inline关键字不应该出现在函数声明中,没有任何作用不说,有时还可能造成编译错误(在包含了sys/compiler.h的情况下,声明中出现inline关键字的部分通常无法编译通过); 
inline关键字仅仅是建议编译器做内联展开处理,而不是强制。在gcc编译器中,如果编译优化设置为-O0,即使是inline函数也不会被内联展开,除非设置了强制内联(__attribute__((always_inline)))属性。

1. GCC的inline
gcc对C语言的inline做了自己的扩展,其行为与C99标准中的inline有较大的不同。

1.1. static inline
GCC的static inline定义很容易理解:你可以把它认为是一个static的函数,加上了inline的属性。这个函数大部分表现和普通的static函数一样,只不过在调用这种函数的时候,gcc会在其调用处将其汇编码展开编译而不为这个函数生成独立的汇编码。除了以下几种情况外: 
函数的地址被使用的时候。如通过函数指针对函数进行了间接调用。这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址。 
其他一些无法展开的情况,比如函数本身有递归调用自身的行为等。
static inline函数和static函数一样,其定义的范围是local的,即可以在程序内有多个同名的定义(只要不位于同一个文件内即可)。 
 注意  
gcc的static inline的表现行为和C99标准的static inline是一致的。所以这种定义可以放心使用而没有兼容性问题。 
要点: 
gcc的static inline相对于static函数来说只是在调用时建议编译器进行内联展开; 
gcc不会特意为static inline函数生成独立的汇编码,除非出现了必须生成不可的情况(如通过函数指针调用和递归调用); 
gcc的static inline函数仅能作用于文件范围内。
1.2. inline
相对于C99的inline来说,GCC的inline更容易理解:可以认为它是一个普通全局函数加上了inline的属性。即在其定义所在文件内,它的表现和static inline一致:在能展开的时候会被内联展开编译。但是为了能够在文件外调用它,gcc一定会为它生成一份独立的汇编码,以便在外部进行调用。即从文件外部看来,它和一个普通的extern的函数无异。举个例子:
foo.c:
/* 这里定义了一个inline的函数foo() */
inline foo() {
    ...;   <- 编译器会像非inline函数一样为foo()生成独立的汇编码
}
void func1() {
    foo(); <- 同文件内foo()可能被编译器内联展开编译而不是直接call上面生成的汇编码
}
而在另一个文件里调用foo()的时候,则直接call的是上面文件内生成的汇编码:
bar.c:
extern foo(); <- 声明foo(),注意不能在声明内带inline关键字
void func2() {
    foo();    <- 这里就是直接call在foo.c内为foo()函数生成的汇编码了
}
重要  
虽然gcc的inline函数的行为很好理解,但是它和C99的inline是有很大差别的。请注意看后面对C99 inline的描述(第 2.2 节 “inline”),以及如何以兼顾GCC和C99的方式使用inline函数。 
要点: 
gcc的inline函数相对于普通extern函数来说只是在同一个文件内调用时建议编译器进行内联展开; 
gcc一定会为inline函数生成一份独立的汇编码,以便其在本文件之外被调用。在别的文件内看来,这个inline函数和普通的extern函数无异; 
c的inline函数是全局性的:在文件内可以作为一个内联函数被内联展开,而在文件外可以调用它。
1.3. extern inline
GCC的static inline和inline都很好理解:看起来都像是对普通函数添加了可内联的属性。但是这个extern inline就千万不能想当然地理解成就是一个extern的函数+inline属性了。实际上gcc的extern inline十分古怪:一个extern inline的函数只会被内联进去,而绝对不会生成独立的汇编码!即使是通过指针应用或者是递归调用也不会让编译器为它生成汇编码,在这种时候对此函数的调用会被处理成一个外部引用。另外,extern inline的函数允许和外部函数重名,即在存在一个外部定义的全局库函数的情况下,再定义一个同名的extern inline函数也是合法的。以下用例子具体说明一下extern inline的特点:
foo.c:
extern inline
int foo(int a)
{
    return (-a);
}
void func1()
{
    ...;
    a = foo(a);   ①
    p_foo = foo;  ②
    b = p_foo(b); ③
}
在这个文件内,gcc不会生成foo函数的汇编码。在func1中的调用点①,编译器会将上面定义的foo函数在这里内联展开编译,其表现类似于普通inline函数。因为这样的调用是能够进行内联处理的。而在②处,引用了foo函数的地址。但是注意:编译器是绝对不会为extern inline函数生成独立汇编码的!所以在这种非要个函数地址不可的情况下,编译器不得不将其处理为外部引用,在链接的时候链接到外部的foo函数去(填写外部函数的地址)。这时如果外部没有再定义全局的foo函数的话就会在链接时产生foo函数未定义的错误。 
假设在另一个文件里面也定义了一个全局函数foo:
foo2.c:
int foo(int a)
{
    return (a);
}
那么在上面那个例子里面,后面一个对foo函数地址的引用就会在链接时被指到这个foo2.c中定义的foo函数去。也就是说:①调用foo函数的结果是a=-a,因为其内联了foo.c内的foo函数;而③调用的结果则是b=b,因为其实际上调用的是foo2.c里面的foo函数! 
extern inline的用法很奇怪也很少见,但是还是有其实用价值的。第一:它可以表现得像宏一样,可以在文件内用extern inline版本的定义取代外部定义的库函数(前提是文件内对其的调用不能出现无法内联的情况);第二:它可以让一个库函数在能够被内联的时候尽量被内联使用。举个例子: 
在一个库函数的c文件内,定义一个普通版本的库函数libfunc:
lib.c:
void libfunc()
{
    ...;
}
然后再在其头文件内,定义(注意不是声明!)一个实现相同的exterin inline的版本:
lib.h:
extern inline libfunc()
{
    ...;
}
那么在别的文件要使用这个库函数的时候,只要include了lib.h,在能内联展开的地方,编译器都会使用头文件内extern inline的版本来展开。而在无法展开的时候(函数指针引用等情况),编译器就会引用lib.c中的那个独立编译的普通版本。即看起来似乎是个可以在外部被内联的函数一样,所以这应该是gcc的extern inline意义的由来。 但是注意这样的使用是有代价的:c文件中的全局函数的实现必须和头文件内extern inline版本的实现完全相同。否则就会出现前面所举例子中直接内联和间接调用时函数表现不一致的问题。 
 重要  
gcc的extern inline函数的用法相当奇怪,使用的范围也非常狭窄:几乎没有什么情况会需要用它。 C99中,也没有关于extern inline这样的描述,所以不建议大家使用extern inline,除非你明确理解了这种用法的意义并且有充足的理由使用它! 
要点: gcc绝对不会为extern inline的函数生成独立汇编码 
extern inline函数允许和全局函数重名,可以在文件范围内替代外部定义的全局函数 
extern inline函数的应用范围十分狭窄,而且行为比较奇怪,不建议使用

2. C99的inline
以下主要描述C99的inline与Gcc不同的部分。对于相同的部分请参考GCC inline的说明。
2.1. static inline
同GCC的static inline(第 1.1 节 “static inline”)。
2.2. inline
C99的inline的使用相当令人费解。当一个定义为inline的函数没有被声明为extern的时候,其表现有点类似于gcc中extern inline那样(C99里面这段描述有点晦涩,原文如下): 
If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
即如果一个inline函数在文件范围内没有被声明为extern的话,这个函数在文件内的表现就和gcc的extern inline相似:在本文件内调用时允许编译器使用本文件内定义的这个内联版本,但同时也允许外部存在同名的全局函数。只是比较奇怪的是C99居然没有指定编译器是否必须在本文件内使用这个inline的版本而是让编译器厂家自己来决定,相当模糊的定义。 
如果在文件内把这个inline函数声明为extern,则这个inline函数的表现就和gcc的inline一致了:这个函数即成为一个“external definition”(可以简单理解为全局函数):可以在外部被调用,并且在程序内仅能存在一个这样名字的定义。 
下面举例说明C99中inline的特性:
inline double fahr(double t)
{
    return (9.0 * t) / 5.0 + 32.0;
}
inline double cels(double t)
{
    return (5.0 * (t - 32.0)) / 9.0;
}
extern double fahr(double);   ①
double convert(int is_fahr, double temp)
{
    return is_fahr ? cels(temp) : fahr(temp);   ②
}
在上面这个例子里,函数fahr是个全局函数:因为在①处将fahr声明为extern,因此在②处调用fahr的时候使用的一定是这个文件内所定义的版本(只不过编译器可以将这里的调用进行内联展开)。在文件外部也可以调用这个函数(说明像gcc的inline一样,编译器在这种情况下会为fahr生成独立的汇编码)。 
而cels函数因为没有在文件范围内被声明为extern,因此它就是前面所说的“inline definition”,这时候它实际上仅能作用于本文件范围(就像一个static的函数一样),外部也可能存在一个名字也为cels的同名全局函数。在②处调用cels的时候编译器可能选择用本文件内的inline版本,也有可能跑去调用外部定义的cels函数(C99没有规定此时的行为,不过编译器肯定都会尽量使用文件内定义的inline版本,要不然inline函数就没有存在的意义了)。从这里的表现上看C99中未被声明为extern的inline函数已经和gcc的extern inline十分相似了:本文件内的inline函数可以作为外部库函数的替代。 
 重要  
C99标准中的inline函数行为定义的比较模糊,并且inline函数有没有在文件范围内被声明为extern的其表现有本质不同。如果和gcc的inline函数比较的话,一个被声明为extern的inline函数基本等价于GCC的普通inline函数;而一个没有被声明为extern的inline函数基本等价于GCC的extern inline函数。 
因为C99的inline函数如此古怪,所以在使用的时候,建议为所有的inline函数都在头文件中创建extern的声明:
foo.h:

extern foo();
而在定义inline函数的c文件内include这个头文件:
foo.c:
#include "foo.h"
inline void foo()
{
    ...;
}
这样无论是用gcc的inline规则还是C99的,都能得到完全相同的结果:foo函数会在foo.c文件内被内联使用,而在外部又可以像普通全局函数一样直接调用。

2.3. extern inline
C99没有见到extern inline的用法。

http://www.cnblogs.com/cnmaizi/archive/2011/01/19/1939686.html

Inline Functions In C

Introduction

GNU C (and some other compilers) had inline functions long before standard C introduced them (in the 1999 standard); this page summarizes the rules they use, and makes some suggestions as to how to actually use inline functions.

The point of making a function inline is to hint to the compiler that it is worth making some form of extra effort to call the function faster than it would otherwise - generally by substituting the code of the function into its caller. As well as eliminating the need for a call and return sequence, it might allow the compiler to perform certain optimizations between the bodies of both functions.

Sometimes it is necessary for the compiler to emit a stand-alone copy of the object code for a function even though it is an inline function - for instance if it is necessary to take the address of the function, or if it can't be inlined in some particular context, or (perhaps) if optimization has been turned off. (And of course, if you use a compiler that doesn't understand inline, you'll need a stand-alone copy of the object code so that all the calls actually work at all.)

There are various ways to define inline functions; any given kind of definition might definitely emit stand-alone object code, definitely not emit stand-alone object code, or only emit stand-alone object code if it is known to be needed. Sometimes this can lead to duplication of object code, which is a potential problem for following reasons:

  1. It wastes space.
  2. It can cause pointers to what is apparently the same function to compare not equal to one another.
  3. It might reduce the effectiveness of the instruction cache. (Although inlining might do that in other ways too.)

If any of these are a problem for you then you will want to use a strategy that avoids duplication. These are discussed below.

C99 inline rules

The specification for inline is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). Unfortunately this isn't freely available. The following possibilities exist:

  • A function where all the declarations (including the definition) mention inline and never extern. There must be a definition in the same translation unit. The standard refers to this as an inline definition. No stand-alone object code is emitted, so this definition can't be called from another translation unit.

    You can1 have a separate (not inline) definition in another translation unit, and the compiler might choose either that or the inline definition.

    Such functions may not contain modifiable static variables, and may not refer to static variables or functions elsewhere in the source file where they are declared.

    In this example, all the declarations and definitions use inline but not extern:

    // a declaration mentioning inline
    inline int max(int a, int b);
    
    // a definition mentioning inline
    inline int max(int a, int b) {
      return a > b ? a : b;
    }

    The function won't be callable from other files; if another file has a definition that might be used instead.

    1 The standard is vague on this point. It says that the inline definition does not forbid an external definition elsewhere, but then that it provides an alternative to an external definition. Unfortunately this doesn't really make clear whether this external definition must actually exist.

    In practice unless you are torture-testing your compiler it will exist: if you wanted to keep your inline function entirely private to one translation unit, you make it static inline.

  • A function where at least one declaration mentions inline, but where some declaration doesn't mentioninline or does mention extern. There must be a definition in the same translation unit. Stand-alone object code is emitted (just like a normal function) and can be called from other translation units in your program.

    The same constraint about statics above applies here, too.

    In this example all the declarations and definitions use inline but one adds extern:

    // a declaration mentioning extern and inline
    extern inline int max(int a, int b);
    
    // a definition mentioning inline
    inline int max(int a, int b) {
      return a > b ? a : b;
    }

    In this example, one of the declarations does not mention inline:

    // a declaration not mentioning inline
    int max(int a, int b);
    
    // a definition mentioning inline
    inline int max(int a, int b) {
      return a > b ? a : b;
    }

    In either example, the function will be callable from other files.

  • A function defined static inline. A local definition may be emitted if required. You can have multiple definitions in your program, in different translation units, and it will still work. Just dropping the inlinereduces the program to a portable one (again, all other things being equal).

    This is probably useful primarily for small functions that you might otherwise use macros for. If the function isn't always inlined then you get duplicate copies of the object code, with the problems described above.

    A sensible approach would be to put the static inline functions in either a header file if they are to be widely used or just in the source files that use them if they are only ever used from one file.

    In this example the function is defined static inline:

    // a definition using static inline
    static int max(int a, int b) {
      return a > b ? a : b;
    }

The first two possibilities go together naturally. You either write inline everywhere and extern in one place to request a stand-alone definition, or write inline almost everywhere but omit it exactly once to get the stand-alone definition.

main is not allowed to be an inline function.

(If you think I've misinterpreted these rules, please let me know!)

(C++ is stricter: a function which is inline anywhere must be inline everywhere and must be defined identically in all the translation units that use it.)

GNU C inline rules

The GNU C rules are described in the GNU C manual, which is included with the compiler. This is freely available if you follow links from e.g. http://gcc.gnu.org. The following possibilities exist:

  • A function defined with inline on its own. Stand-alone object code is always emitted. You can only write one definition like this in your entire program. If you want to use it from other translation units to the one where it is defined, you put a declaration in a header file; but it would not be inlined in those translation units.

    This is of rather limited use: if you only want to use the function from one translation unit then static inline below makes more sense, if not the you probably want some form that allows the function to be inlined in more than one translation unit.

    However it does have the advantage that by defining away the inline keyword, the program reduces to a portable program with the same meaning (provided no other non-portable constructions are used).

  • A function defined with extern inline. Stand-alone object code is never emitted. You can have multiple such definitions and your program will still work. However, you should add a non-inline definition somewhere too, in case the function is not inlined everywhere.

    This provides sensible semantics (you can avoid duplicate copies of the functions' object code) but is a bit inconvenient to use.

    One approach to using this would be to put the definitions in a header file, surrounded by a #if that expands to true either when using GNU C, or when the header has been included from the file that is contain the emitted definitions (whether or not using GNU C). In the latter case the extern is omitted (for instance writing EXTERN and #define-ing that to either extern or nothing). The #else branch would contain just declarations of the functions, for non-GNU compilers.

  • A function defined with static inline. Stand-alone object code may be emitted if required. You can have multiple definitions in your program, in different translation units, and it will still work. This is the same as the C99 rules.

As of release 4.3, GNU C supports the C99 inline rules described above and defaults to them with the -std=c99or -std=gnu99 options. The old rules can be requested in new compilers with the -gnu89-inline option or via thegnu_inline function attribute.

If the C99 rules are in force then GCC will define the __GNUC_STDC_INLINE__ macro. Since GCC 4.1.3, it will define __GNUC_GNU_INLINE__ if the GCC-only rules are in use, but older compilers use these rules without defining either macro. You could normalize the situation with a fragment like this:

#if defined __GNUC__ && !defined __GNUC_STDC_INLINE__ && !defined __GNUC_GNU_INLINE__
# define __GNUC_GNU_INLINE__ 1
#endif

Strategies for using inline functions

These rules suggest several possible models for using inline functions in more or less portable ways.

  1. A simple portable model. Use static inline (either in a common header file or just in one file). If the compiler needs to emit a definition (e.g. to take its address, or because it doesn't want to inline some call) then you waste a bit of space; if you take the address of the function in two translation units then the result won't compare equal.

    For instance, in a header file:

    static inline int max(int a, int b) {
      return a > b ? a : b;
    }

    You can support legacy compilers (i.e. anything without inline) via -Dinline="", although this may waste space if the compiler does not optimize out unused functions..

  2. A GNU C model. Use extern inline in a common header and provide a definition in a .c file somewhere, perhaps using macros to ensure that the same code is used in each case. For instance, in the header file:

    #ifndef INLINE
    # define INLINE extern inline
    #endif
    INLINE int max(int a, int b) {
      return a > b ? a : b;
    }
    

    ...and in exactly one source file:

    #define INLINE
    #include "header.h"

    Supporting legacy compilers is awkward unless you don't mind wasting space and having multiple addresses for the same function; you need to restrict the definitions to a in single translation unit (with INLINE defined to the empty string) and add some external declarations in the header file.

  3. A C99 model. Use inline in a common header, and provide definitions in a .c file somewhere, via externdeclarations. For instance, in the header file:

    inline int max(int a, int b) {
      return a > b ? a : b;
    }

    ...and in exactly one source file:

    #include "header.h"
    extern int max(int a, int b);

    To support legacy compilers, you have to swap the whole thing around so that the declarations are visible in the common header and the definitions are restricted to a single translation unit, with inline defined away.

  4. A complicated portable model. Use macros to choose either extern inline for GNU C, inline for C99, or neither for a definition. For instance, in the header:

    #ifndef INLINE
    # if __GNUC__ && !__GNUC_STDC_INLINE__
    #  define INLINE extern inline
    # else
    #  define INLINE inline
    # endif
    #endif
    INLINE int max(int a, int b) {
      return a > b ? a : b;
    }
    

    ...and in exactly one source file:

    #define INLINE
    #include "header.h"

    Supporting legacy compilers has the same issues as the GNU C model.

Please report any errors.

http://www.greenend.org.uk/rjk/tech/inline.html

http://blog.csdn.net/senafox/article/details/7609006


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值