多目標文件的鏈接
stack.c
#include <stdio.h>
#define STACKSIZE 1000
typedef struct stack {
int data[STACKSIZE];
int top;
} stack;
stack s;
int count = 0;
void pushStack(int d)
{
s.data[s.top ++] = d;
count ++;
}
int popStack()
{
return s.data[-- s.top];
}
int isEmpty()
{
return s.top == 0;
}
link.c
#include <stdio.h>
int a, b;
int main()
{
a = b = 1;
pushStack(a);
pushStack(b);
pushStack(a);
while (! isEmpty()) {
printf("%d\n", popStack());
}
return 0;
}
編譯方式:
gcc -Wall stack.c link.c -o main
提示出錯信息如下:
但是代碼是可以執行的
定義和聲明
static和extern修飾函數
上述編譯出現錯誤的原因是:編譯器在處理函數調用代碼時沒有找到函數原型,只好根據函數調用代碼做隱式聲明,把這三個函數聲明為:
int pushStack(int);
int popStack(void);
int isEmpty(void);
編譯器往往不知道去哪裡找函數定義,像上面的例子,我讓編譯器編譯main.c,而這幾個函數定義卻在stack.c裡,編譯器無法知道,因此可以用extern聲明。修改link.c如下:
#include <stdio.h>
int a, b;
extern void pushStack(int d);
extern int popStack(void);
extern int isEmpty(void);
int main()
{
a = b = 1;
pushStack(a);
pushStack(b);
pushStack(a);
while (! isEmpty()) {
printf("%d\n", popStack());
}
return 0;
}
這樣編譯器就不會報警了。這裡extern關鍵字表示這個標識符具有External Linkage.pushStack這個標識符具有External Linkage指的是:如果link.c和stack.c鏈接在一起,如果pushStack在link.c和stack.c中都聲明(在stack.c中的聲明同時也是定義),那麼這些聲明指的是同一個函數,鏈接後是同一個GLOBAL符號,代表同一個地址。函數聲明中的extern可以省略不寫,不屑extern的函數聲明也表示這個函數具有External Linkage。