从汇编层面研究一下static和inline到底做了什么。

C源码:

#include<stdio.h>

void echo(){
    printf("This is echo");
}

v 
void main(int argc,const char * argv[]){
    echo();    
    echo();
}

AT&T汇编码

    .file    "static_test.c"
    .section    .rodata
.LC0:
    .string    "This is echo"
    .text
    .globl    echo
    .type    echo, @function
echo:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    echo, .-echo
    .globl    main
    .type    main, @function
main:
.LFB1:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movl    $0, %eax
    call    echo
    movl    $0, %eax
    call    echo
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size    main, .-main
    .ident    "GCC: (Debian 5.3.1-7) 5.3.1 20160121"
    .section    .note.GNU-stack,"",@progbits

可以看到在40行和42行调用了两条call指令。
接下里使用static关键词.

当改为

static void echo{
    printf("This is echo");
}

的时候,观察汇编码会发现只有一个地方不同

.LC0:
    .string    "This is echo"
    .text
    .globl    echo
    .type    echo, @function
echo:

就是LC0标签处多了一个.globl echo,让ehco函数在连接全部文件中可以用

当使用了always_inline之后

#include<stdio.h>

static void echo() __attribute__((always_inline));

void echo(){
    printf("This is echo");
};


void main(int argc,const char * argv[]){
    echo();    
    echo();
}

所有函数里面的操作全部被替换成了函数内汇编码,而不是使用call来调用函数

    .file    "static_test.c"
    .section    .rodata
.LC0:
    .string    "This is echo"
    .text
    .globl    main
    .type    main, @function
main:
.LFB1:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size    main, .-main
    .ident    "GCC: (Debian 5.3.1-7) 5.3.1 20160121"
    .section    .note.GNU-stack,"",@progbits