statyczne globale i anonimowe przestrzenie nazw w C ++

11
  1. Dlaczego C ++ wprowadził jakiekolwiek rozróżnienie między statycznymi globałami (powiązanie wewnętrzne) a symbolami w nienazwanej przestrzeni nazw (powiązanie zewnętrzne, ale w żaden sposób nie można odwoływać się do niego z zewnątrz), wprowadzając to drugie?

  2. Czy któryś z tych powodów jest nadal aktualny, czy też są nowe?

  3. Czy są jeszcze miejsca, w których są jeszcze różne, ale arbitralna zasada, że muszą istnieć anonimowe związki globalne (lub zakres nazw)static i jakie są?

  4. W przypadku punktów bonusowych, jeśli nie ma dobrych powodów, aby były różne, czy istnieje prośba o ich wyrównanie?


Kiedy C ++ wprowadził przestrzenie nazw (C ++ 98), a konkretnie przestrzenie bez nazw, globalne statyczne zostały przestarzałe jako przestarzałe i gorsze od nowej rzeczy z entuzjazmem, choć zostało to cofnięte w C ++ 11 :
wycofanie statycznego słowa kluczowego… już nie?

W wersjach wcześniejszych niż C ++ 11 nie można było używać symboli z wewnętrznym łączeniem jako argumentów-szablonów: Dlaczego C ++ 03 wymagał parametrów szablonu, aby mieć zewnętrzne powiązanie?

Deduplikator
źródło
Wygląda na to, że w większości odpowiedziałeś na własne pytanie, z wyjątkiem bitu „implementacja zgodna”; może powinieneś rozważyć usunięcie drugiej połowy i opublikowanie jej jako odpowiedzi? Czy jest tu jeszcze coś bez odpowiedzi?
Kyle Strand,
@KyleStrand Zreformował to wszystko.
Deduplicator,

Odpowiedzi:

3

Nie przypuszczam, że to odpowiada na wszystkie twoje pytania (lub którekolwiek z nich?), Ale kluczową różnicą między deklaracjami statycznymi na poziomie pliku a anonimowymi przestrzeniami nazw jest to, że przestrzenie nazw dotyczą również typów (nie można zadeklarować statictypu w w tym samym sensie, że deklarujesz zmienną), dlatego preferowana jest przestrzeń nazw, więc istnieje jeden idiom do deklarowania danych i typów o zasięgu pliku.

Przykładowo poniższy kod powinien się dobrze skompilować. (Niezbyt przydatne, ponieważ nie można rozróżnić obu typów, ale dozwolone)

#include <iostream>

struct Foobar
{
    int   foo;
    float bar;
};

namespace
{

struct Foobar
{
    double baz;
};

} // namespace

int main()
{
    std::cout << "HELLO!\n";
}

Test na żywo tutaj .

glampert
źródło
Kompiluje się, ponieważ nie używasz Foobar w głównej funkcji.
dshil
Co ważniejsze, co się stanie, jeśli inny plik .cpp zadeklaruje własną wersję struct Foobar? Co gorsza, załóżmy, że teraz class Foobar. Pomyśl o tym, jak planujesz stworzyć konstruktory dla obu z nich.
dgnuff