ref: https://www.geeksforgeeks.org/internal-linkage-external-linkage-c/
導(dǎo)讀
生命周期(scope)和鏈接方式(linkage)很容易混淆,本文主要介紹生命周期和鏈接方式在C++中如何起作用的。
定義
生命周期(scope): 生命周期是指一個標識符(變量、常亮、類、對象、方法)可以訪問的范圍。
鏈接方式(linkage):鏈接描述標識符如何在整個程序或單個翻譯單元中引用相同的實體。
Internal Linkage and External Linkage翻譯單元(Translation Unit ): 翻譯單元是包含源代碼、頭文件和其他依賴項的文件。所有這些源都被組合在一個文件中,用來產(chǎn)生一個單獨的可執(zhí)行對象。以有意義的方式將這些資源鏈接在一起是很重要的。例如,編譯器應(yīng)該知道printf定義位于stdio頭文件中。
說明:生命周期在編譯期間起作用,鏈接方式在鏈接期間起作用。scope is a property handled by compiler, whereas linkage is a property handled by linker.
內(nèi)部鏈接(Internal Linkage): 一個標識符僅在當前翻譯單元使用,通常可以使用關(guān)鍵字static標識為內(nèi)部鏈接。
外部鏈接(External Linkage): 一個標識符在所有的翻譯單元中可以使用,即在所有翻譯單元共享,通??梢允褂藐P(guān)鍵字extern標識為外部鏈接。
舉例
內(nèi)部鏈接
代碼
// Animal.h
#ifndef ANIMAL_H_
#define ANIMAL_H_
void call_me(void);
static int animals = 8;
const int i = 5;
#endif
//Animal.cpp
#include <stdio.h>
#include "Animal.h"
void call_me(void)
{
printf("const int i=%d, static int animals = %d\n", i, animals);
printf("in Animal.cpp &i = %p,&animals = %p\n", &i, &animals);
}
// Feed.cpp
#include <stdio.h>
#include "Animal.h"
int main()
{
printf("before change aninals:");
call_me();
animals = 2;
printf("after change aninals:");
printf("animals = %d\n", animals);
call_me();
printf("in Feed.cpp &i = %p,&animals = %p\n", &i, &animals);
return 0;
}
編譯鏈接
% g++ Feed.cpp Animal.cpp -o Feed
運行
% ./Feed
before change aninals:const int i=5, static int animals = 8
in Animal.cpp &i = 0x10081dfa8,&animals = 0x100822014
after change aninals:animals = 2
const int i=5, static int animals = 8
in Animal.cpp &i = 0x10081dfa8,&animals = 0x100822014
in Feed.cpp &i = 0x10081dfa4,&animals = 0x100822010
分析
在Animal.cpp和Feed.cpp中, 變量i和animals的地址是不同的,即每個文件都是不同的變量。
外部鏈接
代碼
// Animal.h
#ifndef ANIMAL_H_
#define ANIMAL_H_
void call_me(void);
extern int animals ;
extern const int i;
#endif
// Animal.cpp
#include <stdio.h>
#include "Animal.h"
int animals = 8;
const int i = 5;
void call_me(void)
{
printf("const int i=%d, static int animals = %d\n", i, animals);
printf("in Animal.cpp &i = %p,&animals = %p\n", &i, &animals);
}
// Feed.cpp
#include <stdio.h>
#include "Animal.h"
int main()
{
printf("before change aninals:");
call_me();
animals = 2;
printf("after change aninals:");
printf("animals = %d\n", animals);
call_me();
printf("in Feed.cpp &i = %p,&animals = %p\n", &i, &animals);
return 0;
}
編譯鏈接
% g++ Feed.cpp Animal.cpp -o Feed
運行
% ./Feed
before change aninals:const int i=5, static int animals = 8
in Animal.cpp &i = 0x100d14fb4,&animals = 0x100d19010
after change aninals:animals = 2
const int i=5, static int animals = 2
in Animal.cpp &i = 0x100d14fb4,&animals = 0x100d19010
in Feed.cpp &i = 0x100d14fb4,&animals = 0x100d19010
分析
在Animal.cpp和Feed.cpp中, 變量i和animals的地址是相同的,即所有的文件中該變量是共享的。