Literal string initializer for a character array
Asked Answered
A

4

34

In the following rules for the case when array decays to pointer:

An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.

(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)

How to understand the case when the array is "literal string initializer for a character array"? Some example please.

Thanks!

Anzio answered 10/1, 2010 at 4:38 Comment(1)
Related: Exception to array not decaying into a pointer?Restharrow
D
57

The three exceptions where an array does not decay into a pointer are the following:

Exception 1. — When the array is the operand of sizeof.

int main()
{
   int a[10];
   printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */

   int* p = a;
   printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}

Exception 2. — When the array is the operand of the & operator.

int main()
{
    int a[10];
    printf("%p", (void*)(&a)); /* prints the array's address */

    int* p = a;
    printf("%p", (void*)(&p)); /*prints the pointer's address */
}

Exception 3. — When the array is initialized with a literal string.

int main()
{
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}
Distiller answered 10/1, 2010 at 4:49 Comment(5)
I liked your answer much better before all the edits. Concise and answered the question. Now it answers a lot of questions that are not even asked. :-)Sansone
Thanks Prasson. Some question: (1) in Exception 3, so here lvalue "Hello world" is the string literal initializer of char array "a", and therefore "Hello world" does not decay to a pointer? (2) in Exception 2, is "&a" same as the address of the first element of array "a"?Anzio
The answer is (1) yes, (2) no. For (2), on most computers, if you print the values, they will print the same (I don't know of any where they won't). But &a points to the whole array whereas &a[0] points to the first element of a. So, if you print &a + 1 and &a[0] + 1, they will be different even when &a and &a[0] print the same value.Sansone
Yes the value of &a is same as the value of the address of first element of array 'a' but their types are different.Distiller
Thanks Alok. I think a stirng literal is a rvalue and is not a lvalue, since it is the value of some storage in read-only memory, not the storage itself and cannot appear on the left side of =. If I am wrong, so any literal besides string literal can also be lvalue? What does lvalue mean then and what makes a lvalue different from a rvalue?Anzio
B
10

Assume the declarations

char foo[] = "This is a test";
char *bar  = "This is a test";

In both cases, the type of the string literal "This is a test" is "15-element array of char". Under most circumstances, array expressions are implicitly converted from type "N-element array of T" to "pointer to T", and the expression evaluates to the address of the first element of the array. In the declaration for bar, that's exactly what happens.

In the declaration for foo, however, the expression is being used to initialize the contents of another array, and is therefore not converted to a pointer type; instead, the contents of the string literal are copied to foo.

Britnibrito answered 11/1, 2010 at 21:3 Comment(2)
+1 for the clear and concise answer; perhaps the only one here to show that the exception is about the literal string and not the char array it is assigned to (given that both are character arrays).Restharrow
"This is a test" as a string initializer is an array. As an expression it does not decay to a pointer but remains an array. Excellent.Malvin
F
5

This is a literal string initializer for a character array:

char arr[] = "literal string initializer";

Could also be:

char* str = "literal string initializer";

Definition from K&R2:

A string literal, also called a string constant, is a sequence of characters surrounded by double quotes as in "...". A string has type ``array of characters'' and storage class static (see Par.A.3 below) and is initialized with the given characters. Whether identical string literals are distinct is implementation-defined, and the behavior of a program that attempts to alter a string literal is undefined.

Fawnia answered 10/1, 2010 at 4:44 Comment(2)
As Prasoon mentions, these are not the same thingMegaton
Thanks, Eli. So in these examples, what is the string literal iniitalizer of what? And what is "An lvalue of type array-of-T" that does not decay to pointer?Anzio
D
2

It seems like you pulled that quote from the comp.lang.c FAQ (maybe an old version or maybe the printed version; it doesn't quite match with the current state of the online one):

http://c-faq.com/aryptr/aryptrequiv.html

The corresponding section links to other sections of the FAQ to elaborate on those exceptions. In your case, you should look at:

http://c-faq.com/decl/strlitinit.html

Dongdonga answered 10/1, 2010 at 4:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.