On 6/11/19 2:12 AM, Juha Nieminen wrote:
> Chris Vine <chris@cvine--nospam--.
freeserve.co.uk> wrote:
...
>> I would use the expression "stack-allocated array" or more accurately
>> "array with automatic storage duration" for those.
>
> Except that it doesn't cover all the use cases, such as:
>
> struct S
> {
> int values[10];
> };
>
> That's also a static array (rather than a dynamic one), but it isn't
> necessarily stack-allocated. (Whether it's "with automatic storage
> duration" depends on your definition of that expression.
No - it depends upon the standard's definition of that term:
"Block-scope variables not explicitly declared static, thread_local, or
extern have _automatic storage duration_." (6.7.3p1). The term
"automatic storage duration" is italicized, an ISO convention indicating
that this is not merely a statement which uses that term; this statement
constitutes the official definition of that term.
Objects of type S can have any storage duration: static, thread,
automatic, or dynamic, and the storage duration of the values array is
the same as the object in which it resides.
> ... In a way
> it is, as it's automatically disposed of alongside the rest of the struct.
> However, that expression is often used to mean pretty much "in block
> scope", ie. "automatically destroyed when the block ends", which imples
> that it's being used inside a function. I think that's what the keyword
> "auto", short for "automatic storage duration", originally meant in C.)
It still has that meaning in C. It's almost completely useless - it can
only be used at block scope, and is the default for block scope, so it
can always be removed, which is why C++ could get away with giving it a
new completely unrelated meaning.
The keyword "static" has three meanings in C:
1. When used at file scope, it can be used to give an identifier
internal linkage.
2. When used at block scope, it can give an object static storage duration.
3. A declaration of a function parameter as if it were an array actually
declares a pointer to the type of an element of that array. The length
given for that array used to be meaningless, and could be dropped.
Starting in C99, however, if that length is preceded by the keyword
static, it becomes undefined behavior to call that function with a
pointer, if there is any integer from 0 to the one less than the
declared length of that array, for which you cannot deference the result
of adding that integer to that pointer. In principle, no diagnostic is
required, because a compiler cannot always determine whether or not this
rule will be violated, making this seem like a pointless addition to the
language. However, it often is feasible to diagnose this problem, and
good quality implementations will do so when it is feasible.
C++ has the meanings 1 and 2, but not 3. However, it adds yet another
meaning: when applied to a member of a class, "static" indicates that
the member can be accessed without going though an object of the class type.
Because of that ambiguity, I strongly recommend against using "static"
on it's own as an adjective. Use "static storage duration", "internal
linkage", or "static member". I have not figured out a good way to refer
to identifiers declared using option 3.