When should I write the keyword 'inline' for a function/method?

后端 未结 15 2501
清歌不尽
清歌不尽 2020-11-21 06:55

When should I write the keyword inline for a function/method in C++?

After seeing some answers, some related questions:

  • When should I <

15条回答
  •  青春惊慌失措
    2020-11-21 07:03

    C++ inline is totally different to C inline.

    #include 
    extern inline int i[];
    int i [5];
    struct c {
      int function (){return 1;} //implicitly inline
      static inline int j = 3; //explicitly inline
    };
    int main() {
      c j;
      std::cout << i;
    }
    

    inline on its own affects the compiler, assembler and the linker. It is a directive to the compiler saying only emit a symbol for this function/data if it's used in the translation unit, and if it is, then like class methods, tell the assembler to store them in the section .section .text.c::function(),"axG",@progbits,c::function(),comdat or .section .bss.i,"awG",@nobits,i,comdat for data. Template instantiations also go in their own comdat groups.

    This follows .section name, "flags"MG, @type, entsize, GroupName[, linkage]. For instance, the section name is .text.c::function(). axG means the section is allocatable, executable and in a group i.e. a group name will be specified (and there is no M flag so no entsize will be specified); @progbits means the section contains data and isn't blank; c::function() is the group name and the group has comdat linkage meaning that in all object files, all sections encountered with this group name tagged with comdat will be removed from the final executable except for 1 i.e. the compiler makes sure that there is only one definition in the translation unit and then tells the assembler to put it in its own group in the object file (1 section in 1 group) and then the linker will make sure that if any object files have a group with the same name, then only include one in the final .exe. The difference between inline and not using inline is now visible to the assembler and as a result the linker, because it's not stored in the regular .data or .text etc by the assembler due to their directives.

    static inline in a class means this it a type definition and not declaration (allows static member to be defined in the class) and make it inline; it now behaves as above.

    static inline at file scope only affects the compiler. It means to the compiler: only emit a symbol for this function/data if it's used in the translation unit and do so as a regular static symbol (store in.text /.data without .globl directive). To the assembler there is now no difference between static and static inline

    extern inline is a declaration that means you must define this symbol in the translation unit or throw compiler error; if it's defined then treat it as a regular inline and to the assembler and linker there will be no difference between extern inline and inline, so this is a compiler guard only.

    extern inline int i[];
    extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
    extern int i[5]; //declaration now has complete type
    extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
    extern int i[6]; //error, redeclaration with different complete type
    int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
    

    The whole of the above without the error line collapses to inline int i[5]. Obviously if you did extern inline int i[] = {5}; then extern would be ignored due to the explicit definition through assignment.

    inline on a namespace, see this and this

提交回复
热议问题