精华内容
下载资源
问答
  • inline static varaible

    2016-07-28 14:33:37
    void doSomething() ... static int value ; } You must realise that the static variable inside the function, simply put, a global variable hidden to all but the function's scope, meaning that only t
    void doSomething()
    {
       static int value ;
    }

    You must realise that the static variable inside the function, simply put, a global variable hidden to all but the function's scope, meaning that only the function it is declared inside can reach it.

    Inlining the function won't change anything:

    inline void doSomething()
    {
       static int value ;
    }

    There will be only one hidden global variable. The fact the compiler will try to inline the code won't change the fact there is only one global hidden variable.

    Now, if your function is declared static:

    static void doSomething()
    {
       static int value ;
    }

    Then it is "private" for each compilation unit, meaning that every CPP file including the header where the static function is declared will have its own private copy of the function, including its own private copy of global hidden variable, thus as much variables as there are compilation units including the header.

    Adding "inline" to a "static" function with a "static" variable inside:

    inline static void doSomething()
    {
       static int value ;
    }

    has the same result than not adding this "inline" keyword, as far as the static variable inside is concerned.

    展开全文
  • 头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一。于是自己验证。经过arm-none-eabi-gcc下测试后得出结论。 inline 关键字实际上仅是建议内联并...

     头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一。于是自己验证。经过arm-none-eabi-gcc下测试后得出结论。

        inline 关键字实际上仅是建议内联并不强制内联,gcc中O0优化时是不内联的,即使是O2以上,如果该函数被作为函数指针赋值,那么他也不会内联,也必须产生函数实体,以获得该函数地址。经测试c文件中的仅inline函数即使Os优化也不内联,因为没有static,编译认他是全局的,因此像普通函数一样编译了,本c文件也一样通过 bl inline_func 这样的方式调用,不像网上别人说的,本c会内联,其他c文件则通过bl inline_func 方式。加入static 后则内联了。(Os优化等级测试)
        所以在头文件中用inline时务必加入static,否则当inline不内联时就和普通函数在头文件中定义一样,当多个c文件包含时就会重定义。所以加入static代码健壮性高,如果都内联了实际效果上是一样的。(gcc下验证过O0级别includes.h中仅定义inline的函数,编译失败,Os编译成功)

    为什么要在头文件中定义函数呢?
    虽然知道了头文件中用inline函数时要加入static,但是为什么要在头文件中定义函数呢?
    一些简单的封装接口函数,如 open() { vfs_open() } 仅仅是为了封装一个接口,我们不希望耗费一次函数调用的时间,解决方法一是宏,但是作为接口,宏不够清晰。那选择inline,但是如果在c文件中写
    main.c
    inline void open(void)
    {
        vfs_open();
    }
    头文件加声明,外部要使用则不会内联的,因为编译器有个原则,以c文件为单位进行逐个编译obj,每个c文件的编译是独立的,该c文件用到的外部函数都在编译时预留一个符号,只有等到所有obj生成后链接时才给这些符号地址(链接脚本决定地址),所以其他c文件编译时只会看到这个函数的声明而无法知道她的实体,就会像普通函数一样通过bl 一个函数地址,等链接的时候再填入该地址了,他做不到内联展开。
    所以要内联则必须在每个用到它的c文件体现实体,那就只有在头文件了,所以会把这类希望全局使用又希望增加效率的函数实现在头文件中static inline。

    static inline 的坏处
        因为inline 是C99才有的关键字,C89没有,有部分编译器不支持,或者部分支持,如支持__inline 或 __inline__等,所以我们一般会用一个宏定义inline 如:
    #define INLINE    static inline
    不支持inline时:
    #define INLINE    static
        但是这样如果编译器不支持inline 即意味着之前 static inline的函数全部被修改为 static,在头文件中写static会有什么后果呢?
    经过测试果然和我们想的一样,每个c文件包含了该头文件后全部都有了该函数副本。这无疑增大了很多代码量。比如在include.h
    这样的大头文件,几乎每个c文件我们都会包含他,相当于每一C文件都会加入一个 static void func(void){...}  实体。如果是函数宏则不会有这种问题,函数宏是没有实际代码的,没调用他时代码不存在。这就是头文件中用static inline 函数的坏处。但是可以通过优化解决,经过测试,O0优化下在头文件中定义static 函数包含该头文件的三个c文件的确都有了该函数,但是在Os优化下则只有调用了该函数的C文件才有实体。这是由编译器对static函数的特性决定的。总之他的法则和我们想的一致,就是头文件仅仅是单纯的展开,而每个C独立编译,不会因为知道其他个C文件定义了该函数,这个c文件就把他当外部bl了。

     

    关于c文件中的static函数
    static函数除了文件内使用这个功能外,在优化上也有作用,static定义后如果该文件没有函数调用他,那么他意味着没有用,其他文件不可能调用,所以开优化就被优化掉了(已验证),无优化时则还在。这点一定要注意中断函数最好不要写static,中断函数如果没有中断服务函数的,即没有被调用,static可能被优化,当然也不一定,因为没有中间服务函数的独立中断服务函数必须在链接脚本体现,可能需要再链接脚本上加入KEEP参数应该就没问题。

    这里排除非gcc编译器,如code worrior编译器则不同,code worrior是定制型的,通过识别main函数,因此他有主函数枝干可以判断哪些函数被调用,哪些是无用的,但是gcc不同,没有所谓的main,所以三个c文件如果没有static的函数,即使开优化也都会编译出来,他并不知道哪些函数有用,哪些函数无用。而static后他就一定知道他没被调用即无用,所以可以优化掉。

    以上均指arm-none-eabi-gcc环境下测试的结论,其他编译器有些不同。但是c语言的编译规则还是以gcc为标准,即使其他编译器有些不同我们平时编程时还是以这个为标准。
    在codeworrior 编译器上测试,即使0优化依然会把inline内联,有main函数,没有被主干调用的都是无用函数全部被标记UNUSED,不编译,因此上面讨论的当不支持inline时static函数实体过多的问题它也不存在。
    ---------------------
    作者:求知君
    来源:CSDN
    原文:https://blog.csdn.net/huanghui167/article/details/41346663
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • #define inline static const

    2014-11-26 20:00:51
    Static作用分析总结:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。(1...

    #define

     只进行简单的字符替换,无类型检测

    它在程序编译时只是在预处理的过程中实施简单的替换操作而已,但是在替换过程中可能出现各种不安全性问题,不进行参数有效性检查。


    使用#define 而不使用函数的优点

    因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行

    该函数前的地方。这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行。

    因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。而宏只是在预处理的地方把代码展开,不需要额外的空间

    和时间方面的开销,所以调用一个宏比调用一个函数更有效率。



    inline

    1) 产生背景
    inline这个关键字的引入原因和const十分相似,inline 关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中
    表达式形式的宏定义。
    表达式形式的宏定义一例:
       #define ExpressionName(Var1,Var2) (Var1+Var2)*(Var1-Var2)
           这种表达式形式宏形式与作用跟函数类似,但它使用预编译器,没有堆栈,使用上比函数高效。但它只是预编译器上符号表的简单替换,不能进行参数有效性检测及使用C++类的成员访问控制。
    inline 推出的目的,也正是为了取代这种表达式形式的宏定义,它消除了它的缺点,同时又很好地继承了它的优点。inline代码放入预编译器符号表中,高效;它是个真正的函数,调用时有严格的参数检测;它也可作为类的成员函数。
    2) 具体作用
    直接在class类定义中定义各函数成员,系统将他们作为内联函数处理;成员函数是内联函数,意味着:每个对象都有该函数一份独立的拷贝。
    在类外,如果使用关键字inline定义函数成员,则系统也会作为内联函数处理;

     内联函数和普通函数相比可以加快程序的运行速度,但它是以增加程序存储空间为代价的,由于不需要中断调用,在编译内联函数的时候内联函数可以直接被嵌入目标代码中。
            对于短小的代码,inline可以带来一定效率的提升,且与C时代的define(宏)相比,它更安全可靠。宏和内联函数的主要区别如下:
            1. 宏是代码处不加任何验证的简单替代,而内联函数是将代码直接插入调用处,而减少了普通函数调用时的资源消耗。
            2. 宏不是函数,只是在编译前预处理阶段将程序中有关字符串替换成宏体。
            3. inline是函数,但在编译中不单独产生代码,而是将有关代码嵌入到调用处。


      对于一般常量,最好用const和enum替换#define;
      对于类似函数的宏,最好改用inline函数替换#define。




    static
    一、产生背景
    引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现?
    最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。类的静态成员也是这个道理。
    解决方案:因此C++ 中引入了static,用它来修饰变量,它能够指示编译
    器将此变量在程序的静态存储区分配空间保存,这样即实现了目的,又使得此变量的存取范围不变。
    二、具体作用
    Static作用分析总结:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。(1 连接方式:成为内部连接;2 存储形式:存放在静态全局存储区)


    const
    一、产生背景
    a C++有一个类型严格的编译系统,这使得C++程序的错误在编译阶段即可发现许多,从而使得出错率大为减少,因此,也成为了C++与C相比,有着突出优点的一个方面。
    b C中很常见的预处理指令 #define VariableName VariableValue 可以很方便地进行值替代,这种值替代至少在三个方面优点突出:
    一是避免了意义模糊的数字出现,使得程序语义流畅清晰,如下例:
      #define USER_NUM_MAX 107 这样就避免了直接使用107带来的困惑。
    二是可以很方便地进行参数的调整与修改,如上例,当人数由107变为201时,改动此处即可;
    三是提高了程序的执行效率,由于使用了预编译器进行值替代,并不需要为这些常量分配存储空间,所以执行的效率较高。

    然而,预处理语句虽然有以上的许多优点,但它有个比较致命的缺点,即,预处理语
    句仅仅只是简单值替代,缺乏类型的检测机制。这样预处理语句就不能享受C++严
    格类型检查的好处,从而可能成为引发一系列错误的隐患。
    Const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时
    继承它的优点。

    现在它的形式变成了:
    Const DataType VariableName = VariableValue ;
    2) 具体作用
    1.const 用于指针的两种情况分析:
         int const *A;  //A可变,*A不可变
         int *const A;  //A不可变,*A可变
     分析:const 是一个左结合的类型修饰符,它与其左侧的类型修饰符和为一个
    类型修饰符,所以,int const 限定 *A,不限定A。int *const 限定A,不限定*A。
    2.const 限定函数的传递值参数:
         void Fun(const int Var);
         分析:上述写法限定参数在函数体中不可被改变。
    3.const 限定函数的值型返回值:
    const int Fun1();
    const MyClass Fun2();
         分析:上述写法限定函数的返回值不可被更新,当函数返回内部的类型时(如Fun1),已经是一个数值,当然不可被赋值更新,所以,此时const无意义,最好去掉,以免困惑。当函数返回自定义的类型时(如Fun2),这个类型仍然包含可以被赋值的变量成员,所以,此时有意义。
    4. 传递与返回地址: 此种情况最为常见,由地址变量的特点可知,适当使用const,意义昭然。
    5. const 限定类的成员函数:
    class ClassName {
     public:
      int Fun() const;
     .....
    }
      注意:采用此种const 后置的形式是一种规定,亦为了不引起混淆。在此函数的声明中和定义中均要使用const,因为const已经成为类型信息的一部分。
    获得能力:可以操作常量对象。
    失去能力:不能修改类的数据成员,不能在函数中调用其他不是const的函数。


    展开全文
  • inline 链接标记为WEAK,并建议内联 static 链接标记为LOCAL static inlinestatic,同时建议内联 static inline vs inline vs static in C++

    inline

    链接标记为WEAK,并建议内联

    static

    链接标记为LOCAL

    static inline

    同static,同时建议内联

    static inline vs inline vs static in C++

    展开全文
  • inlinestatic inline

    千次阅读 2019-04-24 09:14:16
    inline:在函数声明或定义中函数返回类型前加上关键字inline,即可以把函数指定为内联函数。 内联函数:建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展)。也就是说建议编译器将指定的函数体插入并取代每...
  • inline 函数被调用时,需要出栈入栈。当函数频繁被调用时,则不断地有函数出栈入栈,会造成栈空间或栈内存的大量消耗。所以引入了inlineinline: 在函数声明或定义中函数返回类型前加上关键字inline,即可以把...
  • static inline

    2020-04-29 16:57:12
    ## inline inline仅仅是展开替换,不存在函数入口,如果放在.h中,会重复引用,所以配合static 使用
  • inlinestatic

    2018-11-15 00:09:28
    inline函数 inline函数的目的是解决程序中函数调用的效率问题,也是用内联取代了宏...含static函数 inline在类体中和类外定义成员函数是有区别的,在类体定义的成员函数为inline函数,在类外定义的不是。  a.如...
  • Inline函数   程序执行时,处理器从Memory中读取代码执行。当程序中调用一个函数时,程序跳到存储器中保存函数的位置开始读取代码...Inline Static函数   Static函数告诉编译器其他文件看不到这个函数,因此该函数
  • C/C++中inline/static inline/extern inline的区别及使用
  • extern inline表示该函数是已声明过的了.由于函数本身可以声明多次,所以extern对函数的影响仅仅把函数的隐藏属性显式化了.  extern 对于非函数的对象是有用的,因为对象声明时会带来内存的分配,而用 extern就表示该...
  • inline函数 inlinestatic的区别

    千次阅读 2020-04-20 11:00:16
    inline函数 :在代码里加上inline后,符号解析出现错误, inline函数 :在函数的调用直接代码展开(编译阶段 ) 宏和inline函数有什么区别??? inline函数的优点: 在函数的调用直接展开,没有函数的请栈和开栈 ...
  • inline 类内定义的默认为inline 类外定义的,类内声明为inline,类外定义可省略inline static 类内声明static成员,类外初始化时无需(不能)重复声明static const 类内声明const,类外定义也要带const ...
  • static inline:inline表示内联,在编译时,直接把函数代码拷贝到程序中去,而static inline表示静态内联函数,static是限定本函数只在当前函数中被调用 extern inline:extern告诉编译器函数已经声明过了,为了保证...
  • static inline声明

    2017-10-15 22:42:52
    一、static inline 函数 此声明一般出现在 .h 头文件中。 声明的作用:这类希望全局使用又希望增加效率的函数实现在头文件中static inline。 二、以此方式声明函数易出现编译错误.\Libraries\inc\fsl_clock.h...
  • inlinestatic

    2012-05-20 10:20:56
    // FunsPointArry.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...inline int f1(int a) { static int counter=0; printf("f1:%x,%d\n",&counter,++counter); printf("f1
  • inlinestatic

    千次阅读 2006-05-24 10:59:00
    inline: 在调用处不是call指令,而是插入函数体,适合于短小的函数,省去参数入栈以及执行call、ret指令的过程,提高函数效率。inline指定函数的存储方式。static: 该函数只能访问类的static成员(包括数据和函数)...
  • extern inline表示该函数是已声明过的了.由于函数本身可以声明多次,所以extern对函数的影响仅仅把函数的隐藏属性显式化了. extern 对于非函数的对象是有用的,因为对象声明时会带来内存的分配,而用 extern就表示该...
  • static inline 和 extern inlineLinus是这样解释的: "static inline" means "we have to have this function, if you use it but dont inline it, then make a static version of it in this compi
  • 详解static inline关键字

    2020-09-17 16:47:01
    __STATIC_INLINE void LL_GPIO_SetPinOutputType ( GPIO_TypeDef * GPIOx, uint32_t PinMask, uint32_t OutputType); 我不禁对__STATIC_INLINE产生了好奇。在查看源文件后,发现这个关键字的定义如下 #ifndef __...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 161,336
精华内容 64,534
关键字:

inlinestatic