views:

340

answers:

4

Hi,

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!

+4  A: 

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
As Prasoon mentions, these are not the same thing
BlueRaja - Danny Pflughoeft
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?
Tim
+12  A: 

The three cases(where array does not decay into a pointer) are shown below.

Exception 1) when the array is the operand of a sizeof

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

}

Exception 2) when array is an operand of & 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) or is a literal string initializer for a character array

int main()
{
    char a[]="Hello world"; /* The string is copied on to a local array and is destroyed when the array goes out of scope */

    char *b="Hello world"; /*String is stored in the read-only section of memory.Any attempt to modify such array of chars is Undefined Behavior */ *
}
Prasoon Saurav
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
Tim
Alok
Prasoon Saurav
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
@tim: Read this: http://www.devx.com/tips/Tip/5696
Prasoon Saurav
+2  A: 

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
A: 

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 another array, and is therefore not converted to a pointer type; instead, the contents of the string literal are copied to foo.

John Bode