33

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!

Community
  • 1
  • 1
Tim
  • 1
  • 141
  • 372
  • 590
  • 1
    Related: [Exception to array not decaying into a pointer?](http://stackoverflow.com/questions/17752978/exception-to-array-not-decaying-into-a-pointer) – legends2k Jul 09 '14 at 08:26

4 Answers4

55

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) */
}
Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 1
    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. :-) – Alok Singhal Jan 10 '10 at 04:58
  • 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"? – Tim Jan 10 '10 at 05:03
  • 2
    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. – Alok Singhal Jan 10 '10 at 05:09
  • 1
    Yes the value of &a is same as the value of the address of first element of array 'a' but their types are different. – Prasoon Saurav Jan 10 '10 at 05:11
  • 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? – Tim Jan 10 '10 at 05:18
9

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.

Faheem Mitha
  • 6,096
  • 7
  • 48
  • 83
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    +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). – legends2k Jul 09 '14 at 08:36
  • 1
    `"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. – cdosborn Jun 21 '15 at 04:47
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.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
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

jamesdlin
  • 81,374
  • 13
  • 159
  • 204