c语言 static思考

如下代码

//main.c
#include "static_test.h"

TOKEN token;

int main()  
{
    token = *getToken();

    add();

    printf("after add, &token2.a = %d\n", &token.a);
    printf("after add, token2.a = %d\n", token.a);

    return 0;
}


//static_test.c
#include "static_test.h"

//这里有没有static会有区别 
//static TOKEN token;
TOKEN token;

TOKEN *getToken()  
{
    token.a = 100;

    printf("getToken &a = %d\n", &token.a);
    return &token;
}

void add()  
{
    token.a++;

    printf("add &a = %d\n",&token.a);
    printf("add  a = %d\n",token.a);
}


//static_test.h
#include "staic_test.h"

static TOKEN token;

TOKEN *getToken()  
{
    token.a = 100;

    printf("getToken &a = %d\n", &token.a);
    return &token;
}

void add()  
{
    token.a++;

    printf("add &a = %d\n",&token.a);
    printf("add  a = %d\n",token.a);
}

有static

采用gcc编译 static_test.h static_test.c 输出中间文件static_test.o

chainhelen@iZwz92pw32r9w6beu4jlfpZ:~/tmp$ readelf -s static_test.o 

Symbol table '.symtab' contains 13 entries:  
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS static_test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 token
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     9: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
    10: 0000000000000000    41 FUNC    GLOBAL DEFAULT    1 getToken
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    12: 0000000000000029    65 FUNC    GLOBAL DEFAULT    1 add

这里可以看到token 的Bind是LOCAL,该变量内存是存在.bss段里

无static

chainhelen@iZwz92pw32r9w6beu4jlfpZ:~/tmp$ readelf -s static_test.o 

Symbol table '.symtab' contains 13 entries:  
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS static_test.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     9: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM token
    10: 0000000000000000    41 FUNC    GLOBAL DEFAULT    1 getToken
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    12: 0000000000000029    65 FUNC    GLOBAL DEFAULT    1 add

可以看到这里token 的Bind是GLOBAL,该变量内存不在任何段,标号是COMMOM

区别

  1. 当static_test.o里面token 的 Bind 是LOCAL的时候(有static,只对本文件可见),main.c中 token 就和 static_test.o 是不同地址,不同变量,互不干扰
  2. 当static_test.o里面token 的 Bind 是GLOBAL的时候,main.c中 token 就和 static_test.o 是同一个地址,两个弱符号类型一致,所以stat_test.c 中 对token修改的时候,main.c中token也会相应修改
  3. 指针是无敌的,依然可以直接搞static只对本文件的变量