Chciałbym zauważyć, że istnieje duża różnica między regułą gramatyki o nazwie StorageClass, a co semantycznie jest klasą przechowywania w języku. Reguły gramatyczne mają do czynienia z analizą, a nie semantyczną fazą kompilacji.
Po pierwsze, TDPL, rozdział 8, jest jawnie o kwalifikatorach typów (dla których Walter użył terminu typ konstruktor). Istnieją tylko 3 z nich w D:
const
niezmienne
wspólne
Wszystkie trzy z nich są częścią tego rodzaju, że ich modyfikowania. Nie jest to prawdą w przypadku klas przechowywania, takich jak ref
.
inout
jest to, co TDPL nazywa "symbolem kwalifikatora wieloznacznego", więc jest symbolem zastępczym dla kwalifikatora typu, a nie jest kwalifikatorem typu lub klasą pamięci.
Teraz, co to zajęcia przechowywania lub nie, daję dwa cytaty z TDPL:
Każdy parametr funkcji (base
i exponent
w powyższym przykładzie) ma, oprócz tego typu, opcjonalny klasa pamięci, która decyduje o sposobie przekazywania argumentów do funkcji po wywołaniu.
(od strony 6 - 7)
Chociaż static
nie jest związane z podjęciem argumentów do funkcji, dyskusji tutaj jest właściwe, ponieważ, podobnie jak ref
, static
zastosowane do danych jest klasa magazynowanie, co oznacza wskazanie szczegółów dotyczących przechowywania danych.
(od strony 137)
Ponadto, jest tam linia ta w odniesieniu do klas pamięci w C, która wydaje się być usedquite a bit w wyjaśnieniach dotyczących klas magazynowych w C znaleźć w Internecie:
klasa pamięci określa zakres (widoczność) i czas życia zmiennych i/lub funkcji w ramach Programu C.
Klasa przechowywania nie ma wpływu na typ zmiennej, tylko sposób jej przechowywania. Niestety, nie mogę znaleźć dokładnej listy klas pamięci w D, a ludzie są dość liberalni terminem klasa pamięci, używając go nawet wtedy, gdy nie ma zastosowania. Niemalże każdy atrybutprzypisany do typu zapisu dla modyfikatorów dostępu wydaje się być nazywany klasą pamięci, w zależności od tego, kto mówi. Jednakże, istnieje kilka, które są poza klas przechowywania wątpliwości:
enum (gdy jest stosowany jako oczywistego stała)
extern
leniwy
spośród
ref
zakres
static
lazy
, out
i ref
może być używany do modyfikowania funkcji parametry i wskazują, w jaki sposób są przekazywane, podczas gdy enum
i static
są używane do wskazania sposobu przechowywania zmiennych (nigdzie w przypadku enum
, ponieważ stałe manifestu są wklejane do skopiowania wszędzie tam, gdzie są używane, a nie jako rzeczywiste zmienne). extern
wpływa na powiązanie.
in
jest hybrydą, ponieważ jest to synonim scope const
, a jednocześnie scope
jest klasa przechowywania, const
jest rodzajem kwalifikator.
Dokumentacja online odnosi się również do auto
i synchronized
jako klas przechowywania, choć nie wiem na jakiej podstawie. auto
jest podobna do inout
pod tym względem, że jest symbolem zastępczym (w tym przypadku jest symbolem zastępczym dla typu, a nie kwalifikatorem typu) i dlatego nie wskazuje na sposób przechowywania typu, więc nie sądziłbym, że będzie to klasa pamięci. synchronized
nie modyfikuje zmiennych, a raczej klasy.
__gshared
to prawdopodobnie także klasa pamięci, chociaż jest trochę zabawna, ponieważ robi mniej więcej to, co robi shared
(co jest kwalifikatorem typu), ale nie jest częścią tego typu.
Poza tym, nie wiem. Fakt, że synchronized
jest wymieniony jako klasa pamięci, oznacza, że niektóre z innych (takich jak final
) mogą być, ale (jak synchronized
) nie mają nic wspólnego z przechowywaniem lub łączeniem zmiennych. Więc nie wiem, jak można je uznać za klasy pamięci masowej.
Zapytam jednak grupę dyskusyjną i zobaczę, czy mogę uzyskać bardziej ostateczną listę.
EDIT: Wydaje się, że nie jest ostateczne, oficjalne listę klas przechowywania w D. Termin ten jest stosowany do niemal każdego atrybutu używanego w deklaracji zmiennej, która nie wpływa na jego rodzaj (czyli nie jest to typ kwalifikatora). Wygląda na to, że Walter i Andrei mają tendencję do wypowiadania się na temat kwalifikatorów typu, aby podkreślić, które atrybuty faktycznie wpływają na typ zmiennej, ale termin "klasa pamięci" nie został nigdzie bliżej tego samego poziomu ważności, a kończy się na używaniu. nieformalnie, a nie według jakiejkolwiek rygorystycznej definicji.
auto nie jest symbolem zastępczym dla typu. Jest to tylko nieobowiązkowa klasa starażowania, która jest umieszczana przed deklaracjami bez żadnego innego typu sc lub typu, więc kompilator rozpoznaje ją jako deklarację i podaje typ. niezmienny x = 5; działa dobrze bez auto. – Mafi
@Mafi, * faktycznie *, 'auto' może być uważana za klasę pamięci dla zmiennych stosu, tak jak w C i C++. Słowo kluczowe 'auto' pochodzi z tego użycia, a jego semantyka została * rozwinięta *, aby umożliwić wnioskowanie typu zmiennych bez żadnych innych klas pamięci; dopiero w tym momencie słowo kluczowe stało się użyteczne poza zmiennymi lokalnymi. Jednakże słowo kluczowe 'auto' było rzadkim widokiem przed semantyką wnioskowania typu i nadal jest rzadkim widokiem w C, ponieważ' auto' jest domyślną klasą pamięci dla zmiennych lokalnych. Nazywa się "auto", ponieważ oznacza "automatyczną trwałość", tj. Zmienną stosu. –