การเชื่อมโยงภายนอกและการเชื่อมโยงภายในคืออะไร


337

ฉันต้องการเข้าใจการเชื่อมโยงภายนอกและการเชื่อมโยงภายในและความแตกต่าง

ฉันยังต้องการทราบความหมายของ

constการเชื่อมโยงตัวแปรภายในโดยค่าเริ่มต้นเว้นแต่จะประกาศเป็นexternอย่างอื่น

คำตอบ:


279

เมื่อคุณเขียนแฟ้มการดำเนินงาน ( .cpp, .cxxฯลฯ ) คอมไพเลอร์ของคุณสร้างหน่วยการแปล นี่คือไฟล์ต้นฉบับจากการนำไปใช้ของคุณรวมถึงส่วนหัวทั้งหมดที่คุณ#includeมี

การเชื่อมโยงภายในหมายถึงทุกอย่างเพียง แต่อยู่ในขอบเขตของหน่วยการแปล

การเชื่อมโยงภายนอกหมายถึงสิ่งที่มีอยู่นอกเหนือหน่วยแปลเฉพาะ กล่าวอีกนัยหนึ่งสามารถเข้าถึงได้ผ่านโปรแกรมทั้งหมดซึ่งเป็นการรวมกันของหน่วยการแปลทั้งหมด (หรือไฟล์วัตถุ)


112
ฉันต้องการอัปโหลดนี้ยกเว้นความผิดพลาดอย่างใดอย่างหนึ่ง: หน่วยการแปลไม่ได้ "อย่างใดไฟล์วัตถุ" มันเป็นรหัสที่มาจากการที่คอมไพเลอร์สร้างไฟล์วัตถุ
sbi

4
@ FrankHB อะไรคือสิ่งที่สำคัญกว่าที่คำตอบจะหายไป?
คณิตศาสตร์

2
@Mathematician ขออภัยที่มาช้า ... ฉันคิดว่าปัญหาน่าจะชัดเจน (นอกเหนือจากความแม่นยำของถ้อยคำ) คำตอบนี้ไม่สมบูรณ์เนื่องจากคำถามเกี่ยวกับกฎของconstตัวแปร (เช่นเดียวกับจุดประสงค์) ที่นี่พลาดโดยสิ้นเชิง
FrankHB

294

ดังที่dudewat กล่าวว่าการ เชื่อมโยงภายนอกหมายถึงสัญลักษณ์ (ฟังก์ชั่นหรือตัวแปรทั่วโลก) สามารถเข้าถึงได้ตลอดทั้งโปรแกรมของคุณและการเชื่อมโยงภายในหมายความว่าสามารถเข้าถึงได้ในหน่วยการแปลเดียวเท่านั้น

คุณสามารถควบคุมการเชื่อมโยงของสัญลักษณ์ได้อย่างชัดเจนโดยใช้externและstaticคำหลัก หากไม่ได้ระบุการเชื่อมโยงการเชื่อมโยงเริ่มต้นจะใช้externสำหรับconstสัญลักษณ์ที่ไม่ใช่และstatic(ภายใน) สำหรับconstสัญลักษณ์

// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static

// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static 

โปรดทราบว่าแทนที่จะใช้staticสำหรับการเชื่อมโยงภายในจะเป็นการดีกว่าที่จะใช้เนมสเปซที่ไม่ระบุชื่อซึ่งคุณสามารถใส่classes การเชื่อมโยงสำหรับเนมสเปซนิรนามมีการเปลี่ยนแปลงระหว่าง C ++ 98 และ C ++ 11 แต่สิ่งสำคัญคือพวกเขาไม่สามารถเข้าถึงได้จากหน่วยการแปลอื่น ๆ

namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}

11
การใช้คำสำคัญ "ส่งออก" เน้นความแตกต่างระหว่างฟังก์ชั่นประกาศ 'คงที่' และฟังก์ชั่นประกาศใน namespace ที่ไม่มีชื่อ เพื่อสรุปให้ดีที่สุดที่ฉันสามารถทำได้เทมเพลตฟังก์ชันที่ประกาศพร้อมกับคีย์เวิร์ดการส่งออกในหนึ่งหน่วยการแปลสามารถอ้างถึงฟังก์ชันที่กำหนดในเนมสเปซที่ไม่มีชื่อของหน่วยการแปลที่แตกต่างกันซึ่งเป็นผลมาจากการค้นหาแบบสองเฟส ( ddj.com/showArticle.jhtml?articleID=184401584 )
Richard Corden

จะทำอย่างไรถ้าฉันทำตามนี้: 1.cpp <code> const int ci; </code> 2.cpp <code> ภายนอก int int ci; </code>
Rajendra Uppal

2
@Rajenda คุณจะได้รับข้อผิดพลาดของสัญลักษณ์ที่ยังไม่ได้แก้ไข (ขออภัยในความล่าช้าเก้าเดือนในการตอบฉันพลาดความคิดเห็นนี้ไป)
Motti

4
ข้อมูลที่อาจปรับปรุงคำตอบนี้อย่างมาก: 1) สแตติกไม่เลิกใช้แล้วใน C ++ 11 2) สมาชิก namespace ที่ไม่ระบุชื่อใน C ++ 11 มีการเชื่อมโยงภายในโดยค่าเริ่มต้น ดูstackoverflow.com/questions/10832940/…
อ้างสิทธิ์

2
หมายความว่า "ลิงก์ภายนอก แต่ไม่สามารถเข้าถึงได้จากหน่วยการแปลอื่น" จะเข้าถึงไม่ได้ แต่ยังอยู่ภายนอกได้อย่างไร
szx

101
  • ตัวแปรโกลบอลมีการเชื่อมโยงภายนอกโดยค่าเริ่มต้น ขอบเขตสามารถขยายไปยังไฟล์อื่นนอกเหนือจากที่มีมันได้โดยการexternประกาศให้ตรงกันในไฟล์อื่น
  • ขอบเขตของตัวแปรทั่วโลกสามารถ จำกัด ไฟล์ที่มีการประกาศโดย prefixing staticประกาศด้วยคำหลัก ตัวแปรดังกล่าวจะกล่าวว่ามีการเชื่อมโยงภายใน

ลองพิจารณาตัวอย่างต่อไปนี้:

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  1. ลายเซ็นของฟังก์ชั่นfประกาศfว่าเป็นฟังก์ชั่นที่มีการเชื่อมโยงภายนอก (เริ่มต้น) คำจำกัดความของคำนิยามจะต้องระบุไว้ในภายหลังในไฟล์นี้หรือในหน่วยการแปลอื่น (ที่ระบุด้านล่าง)
  2. maxถูกกำหนดให้เป็นค่าคงที่จำนวนเต็ม เชื่อมโยงเริ่มต้นสำหรับค่าคงที่เป็นภายใน externการเชื่อมโยงของมันจะเปลี่ยนไปภายนอกที่มีคำหลัก ดังนั้นตอนนี้maxสามารถเข้าถึงได้ในไฟล์อื่น
  3. nถูกกำหนดให้เป็นตัวแปรจำนวนเต็ม เชื่อมโยงเริ่มต้นสำหรับตัวแปรที่กำหนดไว้นอกร่างกายของฟังก์ชั่นภายนอก

2.cpp

#include <iostream>
using namespace std;

extern const int max;
extern int n;
static float z = 0.0;

void f(int i)
{
    static int nCall = 0;
    int a;
    //...
    nCall++;
    n++;
    //...
    a = max * z;
    //...
    cout << "f() called " << nCall << " times." << endl;
}
  1. maxมีการประกาศว่าจะมีการเชื่อมโยงภายนอก คำจำกัดความที่ตรงกันสำหรับmax(พร้อมลิงก์ภายนอก) จะต้องปรากฏในไฟล์บางไฟล์ (เช่นเดียวกับใน 1.cpp)
  2. nมีการประกาศว่าจะมีการเชื่อมโยงภายนอก
  3. zถูกกำหนดเป็นตัวแปรระดับโลกที่มีการเชื่อมโยงภายใน
  4. ความหมายของการnCallระบุว่าจะเป็นตัวแปรที่ยังคงความคุ้มค่าคุ้มข้ามสายไปยังฟังก์ชั่นnCall f()แตกต่างจากตัวแปรโลคัลที่มีคลาสหน่วยเก็บข้อมูลอัตโนมัติที่เป็นค่าเริ่มต้นnCallจะถูกกำหนดค่าเริ่มต้นเพียงครั้งเดียวเมื่อเริ่มต้นโปรแกรมและไม่ใช่หนึ่งครั้งสำหรับการเรียกใช้แต่ละf()ครั้ง ตัวระบุคลาสหน่วยเก็บข้อมูลstaticมีผลกับอายุการใช้งานของตัวแปรโลคัลและไม่ใช่ขอบเขต

หมายเหตุ:คำหลักstaticมีบทบาทสองเท่า เมื่อนำมาใช้ในคำจำกัดความของตัวแปรโลกจะระบุการเชื่อมโยงภายใน เมื่อใช้ในคำจำกัดความของตัวแปรท้องถิ่นมันระบุว่าอายุการใช้งานของตัวแปรจะเป็นระยะเวลาของโปรแกรมแทนที่จะเป็นระยะเวลาของฟังก์ชัน

หวังว่าจะช่วย!


2
ที่สำคัญเมื่อใช้ในคำจำกัดความของตัวแปรท้องถิ่นstaticอนุญาตให้เริ่มต้นเดี่ยวขี้เกียจ (ซึ่งจะมีประโยชน์หากคุณต้องการวัตถุ Global-ish แต่ต้องควบคุมเมื่อมันถูกสร้างขึ้นเนื่องจากปัญหาเกี่ยวกับคำสั่งการก่อสร้างทั่วโลกและไม่สามารถจัดสรรแบบไดนามิกได้ ใช้newในขณะที่แผนการเริ่มต้นในเชิงลึกเพิ่มเติมอาจเกินสิ่งที่จำเป็นสำหรับวัตถุในคำถามโดยนัยนี่เป็นปัญหาหลักในระบบฝังตัวที่ใช้ C ++)
JAB

1
ดีมากสอบทำวันของฉัน
Blood-HaZaRd

28

ในแง่ของ 'C' (เนื่องจากคำหลักคงที่มีความหมายแตกต่างกันระหว่าง 'C' และ 'C ++')

ให้พูดคุยเกี่ยวกับขอบเขตที่แตกต่างใน 'C'

ขอบเขต: โดยทั่วไปแล้วฉันจะเห็นอะไรและไกลเท่าไหร่

  1. ตัวแปรท้องถิ่น: ขอบเขตอยู่ภายในฟังก์ชันเท่านั้น มันอยู่ในพื้นที่สแต็คของ RAM ซึ่งหมายความว่าทุกครั้งที่ฟังก์ชั่นได้รับการเรียกตัวแปรทั้งหมดที่เป็นส่วนหนึ่งของฟังก์ชั่นนั้นรวมถึงข้อโต้แย้งฟังก์ชั่นจะถูกสร้างขึ้นใหม่และจะถูกทำลายเมื่อการควบคุมออกไปจากฟังก์ชั่น (เพราะสแต็กจะถูกลบทิ้งทุกครั้งที่ฟังก์ชันส่งคืน)

  2. ตัวแปรคงที่: ขอบเขตของสิ่งนี้สำหรับไฟล์ มันสามารถเข้าถึงได้ทุกที่ในไฟล์
    ที่มีการประกาศ มันอยู่ในส่วน DATA ของ RAM ตั้งแต่นี้สามารถเข้าถึงได้ภายในไฟล์และด้วยเหตุนี้การเชื่อมโยงภายใน ใด ๆ
    ไฟล์อื่น ๆ ไม่สามารถดูตัวแปรนี้ ในความเป็นจริงคำหลัก STATIC เป็นวิธีเดียวที่เราสามารถแนะนำระดับข้อมูลหรือฟังก์ชั่นบางอย่างที่
    ซ่อนอยู่ใน 'C'

  3. ตัวแปรทั่วโลก: ขอบเขตของสิ่งนี้สำหรับทั้งแอปพลิเคชัน มันเป็นรูปแบบที่สามารถเข้าถึงได้ทุกที่ของแอปพลิเคชัน ตัวแปรทั่วโลกยังอยู่ในส่วนข้อมูลเนื่องจากสามารถเข้าถึงได้ทุกที่ในแอปพลิเคชันและด้วยการเชื่อมโยงภายนอก

โดยค่าเริ่มต้นฟังก์ชั่นทั้งหมดอยู่ในระดับโลก ในกรณีที่คุณต้องการซ่อนบางฟังก์ชั่นในไฟล์จากภายนอกคุณสามารถใส่คีย์เวิร์ด static ให้กับฟังก์ชั่นนั้นได้ :-)


12
@Libin: สำหรับ 1) ตัวแปรท้องถิ่นไม่จำเป็นต้องอยู่ใน stack - โดยปกติแล้วจะอยู่ใน stack แต่สามารถอยู่ใน register และในสภาพแวดล้อม ARM พวกเขามักจะอยู่ใน register มากกว่า stack (ขึ้นอยู่กับปัจจัยบางประการ - ระดับการโทรจำนวน ของ args อย่างเป็นทางการ .. )
Artur

4
@Libin: สำหรับ 1) หากคุณคิดว่า 'flush' เป็นการเขียนทับ - นี่เป็นสิ่งที่ผิด ตัวชี้สแต็กถูกย้ายไปที่อื่นแล้ว ไม่มี 'vars ภายในเครื่องที่ถูกต้องก่อนหน้านี้' คือ 'flushed' / ลบล้าง ฯลฯ คุณผสมขอบเขตตัวแปรกับระยะเวลาการจัดเก็บ ขอบเขตบอกจากที่ที่คุณสามารถเข้าถึง var ระยะเวลาการเก็บข้อมูลบอกว่ามันมีอยู่นานแค่ไหน คุณสามารถมีตัวแปรโลคัลที่มีระยะเวลาเก็บข้อมูลแบบสแตติก มันหมายความว่ามันมีชีวิตอยู่ "ตลอดไป" แต่สามารถเข้าถึงได้จากฟังก์ชั่นที่มีการประกาศมา
Artur

2
ลงคะแนนสำหรับแนวคิดที่ไม่ถูกต้องและความเข้าใจผิดที่ชัดเจน พูดอย่างเคร่งครัดไม่มี "โลก" หรือ "ตัวแปร" (เป็นคำนาม) ที่กำหนดไว้ใน C. คุณอาจต้องการอ้างถึง "วัตถุขอบเขตไฟล์" แทนที่จะเป็น "ตัวแปรทั่วโลก" แต่พูดถึง "ขอบเขต" (ใน C มัน เป็นคุณสมบัติของตัวระบุ ) ซึ่งมันเป็นเรื่องไร้สาระ (ทั้งสองคำนิยามไว้ใน C ++ อย่างเป็นทางการโดยมีความหมายแตกต่างกันเล็กน้อย)
FrankHB

@ บทความฉันคิดว่าคุณลืม " เฉพาะ " ใน " มันหมายความว่ามันมีชีวิตอยู่" ตลอดไป "แต่สามารถเข้าถึงได้ (เท่านั้น) จากฟังก์ชั่นที่ประกาศไว้ " - นี่เป็นรายละเอียดที่สำคัญดังนั้นฉันต้องการที่จะชี้ ออกมาอย่างชัดเจน
RobertS สนับสนุน Monica Cellio

14

ก่อนที่จะพูดคุยเกี่ยวกับคำถามที่ว่ามันจะดีกว่าที่จะรู้ว่าคำแปลหน่วย , โปรแกรมและบางแนวคิดพื้นฐานของภาษา C ++ (อันที่จริงการเชื่อมโยงเป็นหนึ่งในพวกเขาในทั่วไป) ได้อย่างแม่นยำ นอกจากนี้คุณยังจะต้องรู้ว่าสิ่งที่เป็นขอบเขต

ฉันจะเน้นประเด็นสำคัญบางอย่างโดยเฉพาะ ที่หายไปในคำตอบก่อนหน้า

เชื่อมโยงเป็นทรัพย์สินของเป็นชื่อซึ่งเป็นที่รู้จักจากการประกาศ ชื่อที่ต่างกันสามารถแสดงถึงเอนทิตีเดียวกันได้(โดยทั่วไปคือวัตถุหรือฟังก์ชัน) ดังนั้นการพูดถึงการเชื่อมโยงของเอนทิตี้มักจะเป็นเรื่องไร้สาระเว้นแต่คุณจะแน่ใจว่าเอนทิตีจะถูกเรียกด้วยชื่อที่ไม่ซ้ำจากการประกาศเฉพาะบางอย่างเท่านั้น

หมายเหตุวัตถุเป็นเอนทิตี แต่ตัวแปรไม่ ขณะที่พูดถึงการเชื่อมโยงของตัวแปรจริงๆแล้วชื่อของเอนทิตีที่แสดงแทน (ซึ่งถูกนำเสนอโดยการประกาศเฉพาะ) นั้นเกี่ยวข้อง การเชื่อมโยงของชื่อเป็นหนึ่งในสาม: ไม่มีการเชื่อมโยงการเชื่อมโยงภายในหรือการเชื่อมโยงภายนอก

หน่วยการแปลที่แตกต่างกันสามารถแบ่งปันการประกาศเดียวกันโดยรวมไฟล์ส่วนหัว / ซอร์ส (ใช่เป็นถ้อยคำมาตรฐาน) ดังนั้นคุณอาจอ้างอิงชื่อเดียวกันในหน่วยการแปลที่แตกต่างกัน หากชื่อที่ประกาศมีการเชื่อมโยงภายนอกข้อมูลประจำตัวของเอนทิตีที่อ้างอิงชื่อจะถูกแชร์เช่นกัน หากชื่อที่ประกาศมีการเชื่อมโยงภายในชื่อเดียวกันในหน่วยการแปลที่แตกต่างกันแสดงถึงเอนทิตีที่แตกต่างกัน แต่คุณสามารถอ้างอิงเอนทิตีในขอบเขตที่แตกต่างกันของหน่วยการแปลเดียวกัน หากชื่อไม่มีการเชื่อมโยงคุณก็ไม่สามารถอ้างอิงเอนทิตีจากขอบเขตอื่น ๆ

(อุ๊ปส์ ... ฉันพบสิ่งที่ฉันพิมพ์แล้วค่อนข้างเพียงแค่ใช้ถ้อยคำมาตรฐานซ้ำ... )

นอกจากนี้ยังมีประเด็นที่สับสนอื่น ๆ ซึ่งไม่ได้ครอบคลุมอยู่ในข้อกำหนดภาษา

  1. การเปิดเผย (ของชื่อ) นอกจากนี้ยังเป็นทรัพย์สินของชื่อประกาศ แต่มีความแตกต่างกันในการเชื่อมโยงความหมาย
  2. การมองเห็น (จากผลข้างเคียง) นี้ไม่เกี่ยวข้องกับหัวข้อนี้
  3. ทัศนวิสัย (ของสัญลักษณ์) ความคิดนี้สามารถนำมาใช้โดยการใช้งานที่เกิดขึ้นจริง ในการนำไปปฏิบัติดังกล่าวสัญลักษณ์ที่มีการแสดงผลเฉพาะในรหัสวัตถุ (ไบนารี) มักจะเป็นเป้าหมายที่แมปจากคำนิยามเอนทิตีซึ่งมีชื่อที่มีการเชื่อมโยงเฉพาะที่เหมือนกันในรหัสต้นทาง (C ++) อย่างไรก็ตามมันมักจะไม่รับประกันแบบหนึ่งต่อหนึ่ง ตัวอย่างเช่นสัญลักษณ์ในอิมเมจไลบรารีแบบไดนามิกสามารถระบุได้เฉพาะในอิมเมจนั้นภายในจากซอร์สโค้ด (เกี่ยวข้องกับส่วนขยายบางอย่างโดยทั่วไป__attribute__หรือ__declspec) หรือตัวเลือกคอมไพเลอร์และภาพไม่ใช่โปรแกรมทั้งหมดหรือไฟล์อ็อบเจ็กต์ที่แปลจากหน่วยการแปลดังนั้นจึงไม่มีแนวคิดมาตรฐานที่สามารถอธิบายได้อย่างถูกต้อง เนื่องจากสัญลักษณ์ไม่ใช่คำศัพท์เชิงบรรทัดฐานใน C ++ จึงเป็นเพียงรายละเอียดการนำไปใช้งานแม้ว่าส่วนขยายของภาษาถิ่นที่เกี่ยวข้องอาจถูกนำมาใช้อย่างกว้างขวาง
  4. การเข้าถึง ใน C ++ นี้มักเกี่ยวกับคุณสมบัติของสมาชิกคลาสหรือคลาสพื้นฐานซึ่งเป็นแนวคิดที่แตกต่างอีกครั้งที่ไม่เกี่ยวข้องกับหัวข้อ
  5. ทั่วโลก ใน C ++ หมายถึง "global" หมายถึงบางส่วนของ global namespace หรือ global namespace scope ส่วนหลังเทียบเท่ากับขอบเขตไฟล์ในภาษา C ทั้งใน C และ C ++ การเชื่อมโยงไม่มีส่วนเกี่ยวข้องกับขอบเขตแม้ว่าขอบเขต (เช่นการเชื่อมโยง) จะเกี่ยวข้องกับตัวระบุ (ใน C) หรือชื่อ (ใน C ++) ที่แนะนำโดยการประกาศบางอย่าง

กฎการเชื่อมโยงของขอบเขต namespace constตัวแปรเป็นสิ่งที่พิเศษ (และโดยเฉพาะอย่างยิ่งแตกต่างกันไปconstวัตถุประกาศในขอบเขตแฟ้มในภาษา C ซึ่งยังมีแนวคิดของการเชื่อมโยงของตัวระบุ) ตั้งแต่ODRจะถูกบังคับใช้โดย C ++ มันเป็นสิ่งสำคัญที่จะให้ไม่เกินหนึ่งนิยามของตัวแปรเดียวกันหรือฟังก์ชั่นที่เกิดขึ้นในโปรแกรมทั้งหมดยกเว้นสำหรับinlineฟังก์ชั่น หากไม่มีกฎพิเศษดังกล่าวconstการประกาศconstตัวแปรที่ง่ายที่สุดด้วย initializers (เช่น= xxx) ในส่วนหัวหรือไฟล์ต้นฉบับ (มักจะเป็น "ไฟล์ส่วนหัว") รวมอยู่ในหลายหน่วยการแปล (หรือรวมอยู่ในหนึ่งหน่วยการแปลมากกว่าหนึ่งครั้ง) แม้จะไม่ค่อยมี) ในโปรแกรมที่จะละเมิด ODR ซึ่งทำให้ใช้งานได้const ไม่สามารถแทนที่มาโครที่มีลักษณะคล้ายวัตถุบางตัวได้


3
คำตอบนี้ฟังดูมีความเชี่ยวชาญมากและอาจแม่นยำมาก (ฉันไม่สามารถตัดสินได้) แต่ส่วนใหญ่แล้วจะไม่เข้าใจเท่าที่ต้องการโดยผู้คนจำนวนมากมองคำถามนี้ที่นี่แทนที่จะอ่านรายละเอียดภาษาโดยตรง อย่างน้อยสำหรับความต้องการของฉันฉันจะยึดคำตอบที่ยอมรับแล้ว แต่ก็ยังขอบคุณที่ให้ข้อมูลเชิงลึกเกี่ยวกับภาษา 👍🏻
WEDI

8

ฉันคิดว่าการเชื่อมโยงภายในและภายนอกใน C ++ให้คำอธิบายที่ชัดเจนและรัดกุม:

หน่วยการแปลหมายถึงไฟล์การนำไปใช้ (.c / .cpp) และไฟล์ส่วนหัว (.h / .hpp) ทั้งหมดที่มี หากวัตถุหรือฟังก์ชั่นภายในหน่วยการแปลนั้นมีการเชื่อมโยงภายในสัญลักษณ์ที่ระบุนั้นจะปรากฏแก่ผู้เชื่อมโยงภายในหน่วยการแปลนั้นเท่านั้น หากวัตถุหรือฟังก์ชั่นมีการเชื่อมโยงภายนอก linker สามารถมองเห็นได้เมื่อประมวลผลหน่วยการแปลอื่น ๆ คำสำคัญคงที่เมื่อใช้ใน namespace ส่วนกลางบังคับให้สัญลักษณ์มีการเชื่อมโยงภายใน คำหลักภายนอกจะส่งผลให้มีสัญลักษณ์ที่มีการเชื่อมโยงภายนอก

คอมไพเลอร์เริ่มต้นการเชื่อมโยงของสัญลักษณ์เช่นนั้น:

ตัวแปรโกลบอลที่ไม่ใช่ const มีการเชื่อมโยงภายนอกโดยค่าเริ่มต้น
ตัวแปรโกลบอล Const มีการเชื่อมโยงภายในโดยค่าเริ่มต้น
ฟังก์ชั่นมีการเชื่อมโยงภายนอกโดยค่าเริ่มต้น


6

การเชื่อมโยงกำหนดว่าตัวระบุที่มีชื่อเหมือนกันอ้างถึงวัตถุฟังก์ชันหรือเอนทิตีอื่น ๆ แม้ว่าตัวระบุเหล่านั้นจะปรากฏในหน่วยการแปลที่แตกต่างกันหรือไม่ การเชื่อมโยงของตัวระบุขึ้นอยู่กับวิธีการประกาศ การเชื่อมโยงมีสามประเภท:

  1. การเชื่อมโยงภายใน : ตัวระบุสามารถมองเห็นได้ภายในหน่วยการแปลเท่านั้น
  2. ลิงก์ภายนอก : สามารถดูตัวระบุ (และอ้างอิง) ในหน่วยการแปลอื่น ๆ
  3. ไม่มีการเชื่อมโยง : ตัวระบุสามารถเห็นได้ในขอบเขตที่กำหนดไว้เท่านั้น การเชื่อมโยงไม่ส่งผลกระทบต่อการกำหนดขอบเขต

c ++ เท่านั้น : คุณยังสามารถมีการเชื่อมโยงระหว่าง C ++ และไม่ใช่รหัส c ++ เศษซึ่งเรียกว่าการเชื่อมโยงภาษา

ที่มา: IBM Program Linkage


5

เป็นพื้น

  • extern linkage ตัวแปรจะปรากฏในไฟล์ทั้งหมด
  • internal linkage ตัวแปรจะปรากฏในไฟล์เดียว

อธิบาย: ตัวแปร const เชื่อมโยงภายในโดยค่าเริ่มต้นเว้นแต่จะประกาศเป็นอย่างอื่นภายนอก

  1. โดยค่าเริ่มต้นตัวแปรทั่วโลกคือ external linkage
  2. แต่constตัวแปรทั่วโลกคือinternal linkage
  3. extern constตัวแปรพิเศษระดับโลกคือexternal linkage

วัสดุที่ดีเกี่ยวกับการเชื่อมโยงใน C ++

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/


1

ใน C ++

ตัวแปรใด ๆ ที่ขอบเขตไฟล์และที่ไม่ซ้อนอยู่ภายในคลาสหรือฟังก์ชันสามารถมองเห็นได้ตลอดหน่วยการแปลทั้งหมดในโปรแกรม สิ่งนี้เรียกว่าการเชื่อมโยงภายนอกเพราะในเวลาเชื่อมโยงชื่อจะปรากฏแก่ผู้เชื่อมโยงทุกที่ภายนอกหน่วยการแปลนั้น

ตัวแปรทั่วโลกและฟังก์ชั่นสามัญมีการเชื่อมโยงภายนอก

วัตถุคงที่หรือชื่อฟังก์ชั่นที่ขอบเขตไฟล์เป็นหน่วยการแปล ที่เรียกว่าเป็น Internal Linkage

การเชื่อมโยงหมายถึงองค์ประกอบที่มีที่อยู่ในลิงก์ / เวลาโหลดเท่านั้น ดังนั้นการประกาศคลาสและตัวแปรโลคัลไม่มีการเชื่อมโยง


const global vars มีการเชื่อมโยงภายใน
Blood-HaZaRd
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.