Dlaczego te same nazwane zewnętrzne zmienne lokalne w różnych blokach mają różne powiązania między kompilatorami w c ++?

12

Podczas gdy właśnie sprawdzałem, które powiązania są przyznawane zewnętrznym zmiennym lokalnym
, odkryłem, że niektóre kompilatory działają inaczej

na przykład, jeśli testowałem poniżej kodu,
jak widać w komentarzach, zmienne varmają różne powiązania

// 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;
        }
    }
}       

wynik to

  • g ++: „100 10 10”
  • clang ++: „100 100 100” (msvc ++)

Widzę z wyniku, że jeśli są więcej niż dwa zagnieżdżone bloki,
g ++ po prostu przyznaje zewnętrzne powiązania ze zmiennymi

Mógłbym znaleźć pokrewną frazę w standardzie,
ale wciąż jest niejasna, ponieważ kompilatory różnią się jej zachowaniem
( https://eel.is/c++draft/basic.link#6 )

Obawiam się, że mój angielski jest zły, więc nie mogę go poprawnie zrozumieć.
Jeśli ktoś ma pojęcie, które kompilatory dobrze odpowiadają standardowi
i jeśli to możliwe, czy ktoś mógłby opracować to, co mówi standard dla mnie?

hyuk myeong
źródło
1
Powiązane stackoverflow.com/questions/41978949/... Uważam, że to błąd gcc, standard podaje przykład z f()funkcją, a najbardziej extern void f()wewnętrzny ma wewnętrzne powiązanie - varpowinno mieć również wewnętrzne powiązanie, ponieważ odnosi się do tego samego „bytu”.
KamilCuk
Deklaracje zakresu blokowego IMO podmiotów z zewnętrznym powiązaniem są Złe, a językiem byłoby lepiej z ich banowaniem
MM
@MM: Jednostki modułowe to robią!
Davis Herring

Odpowiedzi:

4

Jest to przedmiotem otwartego wydania CWG1839 . Obecny intencją jest, że zachowanie Clang i MSVC jest poprawna.

Davis Herring
źródło