เหตุใดตัวแปร extern แบบโลคอลในบล็อกที่แตกต่างกันจึงได้รับการเชื่อมโยงที่แตกต่างกันระหว่างคอมไพเลอร์ใน c ++


12

ในขณะที่ฉันกำลังตรวจสอบว่ามีการเชื่อมโยงใด
บ้างที่อนุญาตให้ตัวแปรท้องถิ่นภายนอกฉันพบว่าพฤติกรรมที่แตกต่างระหว่างคอมไพเลอร์

เช่นถ้าฉันทดสอบโค้ดด้านล่าง
ตามที่คุณเห็นในตัวแปรข้อคิดเห็นvarมีลิงค์ต่างกัน

// foo.cpp
int var = 10;                // external linkage

// main.cpp
#include <iostream>

static int var = 100;        // internal linkage

int main() {
    extern int var;          // internal linkage
    std::cout << var << std::endl;
    {
        extern int var;      // g++: external linkage , clang++: internal linkage
        std::cout << var << std::endl;
        {
            extern int var;  // g++: external linkage , clang++: internal linkage
            std::cout << var << std::endl;
        }
    }
}       

ผลลัพธ์ที่ได้คือ

  • g ++: "100 10 10"
  • เสียงดังกังวาน ++: "100 100 100" (msvc ++)

ฉันเห็นได้จากผลลัพธ์ว่าหากมีบล็อกซ้อนกันมากกว่าสองบล็อก
g ++ เพียงให้การเชื่อมโยงกับตัวแปรภายนอก

ฉันสามารถค้นหาวลีที่เกี่ยวข้องในมาตรฐาน
แต่ก็ยังไม่ชัดเจนเนื่องจากพฤติกรรมของมันแตกต่างกันโดยคอมไพเลอร์
( https://eel.is/c++draft/basic.link#6 )

ฉันกลัวว่าภาษาอังกฤษของฉันไม่ดีดังนั้นฉันจึงไม่สามารถรับมันได้อย่างถูกต้อง
หากมีคนมีความคิดว่าคอมไพเลอร์ตัวใดที่ทำตามมาตรฐานได้ดี
และถ้าเป็นไปได้


1
stackoverflow.com/questions/41978949/…ที่เกี่ยวข้องฉันเชื่อว่าเป็นข้อผิดพลาด gcc มาตรฐานให้ตัวอย่างกับf()ฟังก์ชั่นและด้านในสุดextern void f()มีการเชื่อมโยงภายใน - varควรมีการเชื่อมโยงภายในที่นี่เพราะมันหมายถึง "นิติบุคคล" เดียวกัน
KamilCuk

IMO บล็อกการประกาศขอบเขตของเอนทิตีที่มีการเชื่อมโยงภายนอกเป็นสิ่งที่ชั่วร้ายและภาษาจะดีขึ้นหากใช้การห้าม
MM

@MM: หน่วยโมดูลทำเช่นนั้น!
Davis Herring

คำตอบ:


4

นี่คือเรื่องของปัญหาที่เปิดCWG1839 เจตนาในปัจจุบันคือพฤติกรรมของ Clang และ MSVC นั้นถูกต้อง

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