What are the storage classes in D?
d
Solution
I would point out that there is a big difference between a grammar rule named StorageClass, and what is semantically a storage class in the language. The grammar rules have to do with parsing, not the semantic phase of compilation.
First off, TDPL, chapter 8, is explicitly about type qualifiers (for which Walter used the term type constructor). There are only 3 of them in D:
const immutable shared
All three of them are a part of the type that they modify. Such is not true with storage classes such as `ref`.
`inout` is what TDPL calls a "wildcard qualifier symbol," so it's a placeholder for a type qualifier rather than really being either a type qualifer or a storage class.
Now, as to what's a storage classes or not, I give two quotes from TDPL:
Each function parameter (`base` and `exponent` in the example above) has, in addition to its type, an optional storage class that decides the way that arguments are passed to the function when invoked.
(from pages 6 - 7)
Although `static` is not related to passing arguments to functions, discussing it here is appropriate because, just like `ref`, `static` applied to data is a storage class, meaning an indication about a detail regarding how data is stored.
(from page 137)
Also, there's this line with regards to storage classes in C which seems to be used quite a bit in explanations on storage classes in C found online:
A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program.
A storage class has no effect on the type of a variable, just how it's stored. Unfortunately, I can't find an exact list of storage classes in D, and people are quite liberal with the term storage class, using it even when it doesn't apply. Pretty much any attribute applied to a type save for access modifiers seems to get called a storage class, depending on who's talking. However, there are a few which are beyond a doubt storage classes:
enum (when used as a manifest constant) extern lazy out ref scope static
`lazy`, `out`, and `ref` can be used to modify function parameters and indicate how they're passed, whereas `enum` and `static` are used to indicate how the variables are stored (which is nowhere in the case of `enum`, since manifest constants are copy-pasted everywhere that they're used rather than being actual variables). `extern` affects linkage.
`in` is a hybrid, since it's a synonym for `scope const`, and while `scope` is a storage class, `const` is a type qualifier.
The online documentation also refers to `auto` and `synchronized` as storage classes, though I don't know on what basis. `auto` is like `inout` in that it's a placeholder (in its case a placeholder for a type rather than a type qualifier) and therefore indicates nothing about how a type is stored, so I wouldn't have thought that it would be a storage class. `synchronized` doesn't modify variables but rather classes.
`__gshared` is probably a storage class as well, though it's a bit funny, since it does more or less what `shared` (which is a type qualifier) does, but it's not part of the type.
Beyond that, I don't know. The fact that `synchronized` is listed as a storage class implies that some of the others (such as `final`) might be, but (like `synchronized`) they have nothing to do with how variables are stored or linked. So, I don't know how they could be considered storage classes.
I'll ask on the newsgroup though and see if I can get a more definitive list.
EDIT: It seems that there is no definitive, official list of storage classes in D. The term is used for almost any attribute used on a variable declaration which doesn't affect its type (i.e. not a type qualifier). It seems that Walter and Andrei tend to make a big point about the type qualifiers to underline which attributes actually affect the type of a variable, but the term storage class hasn't been given anywhere near the same level of importance and ends up being used informally rather than per any rigorous definition.
Problem
Up until now I was under the impression that things like `immutable` and `const` were storage classes. In a recent video (at around 11:55) Walter Bright states that `immutable` is not a storage class, but rather it's a type constructor. In the official documentation, `immutable`, `const`, and among many other keywords, are listed as being storage classes: ``` StorageClass: abstract auto const deprecated enum extern final immutable inout shared nothrow override pure __gshared Property scope static synchronized ``` Is this list wrong? Some of it doesn't make sense(e.g., deprecated, override). I know `static` and `ref` are storage classes, but what's the rest? And which one of the keywords in D are type constructors?