Reputation: 55
I read that while using character pointer declaration first the string literal is getting stored in static storage and then pointer to it is returned. but is same happening while using literals in char array?
here I know "instatic" gets stored in static storage because it is char literals and then test receives the address of the first character.
char *test = "instatic";
but in this declaration it also uses char literals and are they first located in static storage and then they get copied to stack?
char test[] = "instatic?";
Upvotes: 1
Views: 87
Reputation: 180201
I read that while using character pointer declaration first the string literal is getting stored in static storage and then pointer to it is returned.
That's a somewhat confusing way to describe it, as if there were some kind of special case behavior. In fact, that behavior falls out naturally from other, more basic aspects of the language specification:
A string literal represents an array of char
with static storage duration.
Expressions of array type, such as string literals, decay to pointers under most circumstances. Specifically:
Except when it is the operand of the
sizeof
operator, ortypeof
operators, or the unary&
operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue.
(C23 6.3.2.1/3)
Thus, when you have a string literal as the initializer for anything other than an array, it is automatically converted to a pointer. In your particular case, that pointer is suitable for initializing pointer variable test
, so all is good.
but is same happening while using literals in char array?
No. As the excerpt above says, a string literal used as the initializer for an array in fact is a special case. The array decay that usually applies does not occur here. Instead, this case is covered with its own initialization rule:
An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
(C23 6.7.10/15)
and are they first located in static storage and then they get copied to stack?
If the variable being initialized has static storage duration (on account of being declared at file scope or with the static
storage-class specifier) then probably not. Semantically, such variables have their initial values already when execution of the program begins. And, such variables generally do not live on the stack.
But if the variable being initialized has automatic storage duration -- that is, it is an ordinary local variable -- then (more or less) each entry into its scope produces a new object, which must be initialized. The initial value needs to be stored somewhere else, and indeed copied in every time. The source from which it is initialized is not directly visible to the program, however, and in practice, it might or might not be analogous to the storage for the string-literal initializer in the pointer case.
Upvotes: 4
Reputation: 222724
Formally, a string literal is text in source code that is a sequence of characters enclosed in "
marks, optionally with an encoding prefix of u8
, u
, U
, or L
, per C 2018 6.4.5 1.
In the abstract model of computing used in the C standard, any string literal, regardless of how it is used, results in the creation of an array of static storage duration that is initialized with the contents of the string, including a terminating null character, per 6.4.5 6.
That static array might or might not appear in the actual program generated by a compiler, depending on how it is used and how the compiler optimizes the program. In other words, the abstract program described by the C standard always contains a static array for a string literal, but the actual program produced by a C compiler, with optimization, might produce the same behavior as the abstract program without actually using a separate static array for the string literal, per 5.1.2.3 6.
In the case of char *test = "instatic";
, the compiler generally must create the static array so that test
can point to it. (This might not occur if test
is not used or perhaps if only individual characters from the array are used, as the compiler could then perform some optimizations that make the full array unnecessary.)
In the case of char test[] = "instatic?";
appearing at file scope, a compiler typically produces object code that defines the array test
with the contents of the string, so a separate static array for the string is not needed. This is a form of optimization: In the abstract model of computing, an array for the string is created, separate memory is allocated for test
, and the contents of the string are copied into the array. However, in practice, the contents of the string are made to be the initial contents of memory for the array as part of the program loading process.
In the case of char test[] = "instatic?";
appearing at block scope (inside a function), the compiler generally needs to create that separate static array for the string, because, each time execution of the block begins, the compiler has to allocate memory for the test
array and then initialize it. This cannot be made part of the program loading process because it has to happen multiple times during program execution. Again, optimization may be able to reduce this, depending on circumstances.
Upvotes: 4