-1

I have :

void func()
{
    char *s;
    strcpy(s,"bla bla");
}

Is "bla bla" stored somewhere? is it considered "const char *" even if I didn't defined it??

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
user1047069
  • 935
  • 2
  • 13
  • 25
  • 1
    Your program invokes undefined behaviour (there is no space allocated in `s` to hold the string), `"bla bla"` may be stored somewhere, it may also not be. It may also make [demons come out of your nose](http://www.catb.org/jargon/html/N/nasal-demons.html). – Kninnug Dec 14 '13 at 21:29
  • 3
    @Kninnug: Where is the UB? And what makes you think `"bla bla"` has no storage? It's a string literal and sits happily in the static data section of the process. – bitmask Dec 14 '13 at 21:34
  • 1
    @bitmask copying it into `s` while `s` is an uninitialized pointer is undefined behaviour. The compiler may very well choose to optimize `"bla bla"` away because it can't go anywhere. – Kninnug Dec 14 '13 at 21:37
  • 3
    @Kninnug I have no idea what you are talking about. Have you seen an array before? – Pascal Cuoq Dec 14 '13 at 21:58
  • 4
    @PascalCuoq I see that the question has been edited rendering my comments moot. Check the revision history to see what I was talking about. – Kninnug Dec 14 '13 at 22:02
  • @Kninnug: Sure, I agree with the uninitialised pointer variable. But the static data looks fine to me. Since `strcpy` should have external linkage, the compiler shouldn't be able to figure out that mayhem will happen, regardless of the content of the array. – bitmask Dec 14 '13 at 22:33
  • @PascalCuoq Yes, he surely has. You should consider that the post was edited -- just *think* a bit, and you will see that Kninnug is perfectly right about the UB. –  Dec 14 '13 at 22:36
  • @bitmask The UB is right here in the code: `strcpy(uninitializedPointer, "string literal");`. Also, Kninnug was not talking about `strcpy()`, but about the string literal, which has `static` storage duration, and it could be optimized away because of the UB. –  Dec 14 '13 at 22:37
  • My apologies, I see now that the question was edited into a completely different question on its second version. – Pascal Cuoq Dec 14 '13 at 23:33
  • 1
    @reuben You changed the string literal used as an expression (C99 6.4.5) into an array initializer (C99 6.7.8:14). This is not a good idea when editing a question **about string literals**. – Pascal Cuoq Dec 14 '13 at 23:51
  • @PascalCuoq Excellent point -- one I'd overlooked. Rather than entirely reverting my edit, it might be better to replace it with a better alternative. One way or the other, I was primarily attempting to improve the usefulness of this question. In retrospect, my efforts were moot anyway. – reuben Dec 14 '13 at 23:59

2 Answers2

2

String literals are nameless array objects, which are stored in static memory, i.e. the same memory that stores global variables. String literals live forever: they exist when the program begins and they persist till the program ends (just like global variables, again).

Note however, that in your code sample it is "blah blah" that's string literal. But your s is just a local variable initialized (by copying data) from string literal. Your s has the same lifetime as any other local variable - it exists as long as the control passes through func.

Note also that string literal in C is not considered const chart *, as you seem to incorrectly believe. The type of "blah blah" in C language is actually char [10]. The array type can decay to pointer type, but even in that case it will be char * and not const char *.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
-2

"blah blah" is stored on the stack, just like any other automatic variable or array declared inside a function.

The construction

char s[] = "blah blah";

is equivalent to

char s[] = {'b', 'l', 'a', 'h', ' ', 'b', 'l', 'a', 'h', '\0'};

and it initializes the array.

You can treat arrays of chars as char * const, because they behave in nearly the same way as arrays, but technically speaking, an array is an array, and a pointer is a pointer. This is not, however the same as const char *. char * const means the pointer cannot be modified, const char * means the memory cannot be modified through that pointer.

Michał Trybus
  • 11,526
  • 3
  • 30
  • 42
  • 2
    I did not downvote, but stating that `"blah blah"` is stored on the stack is incorrect. All string literals are objects with static storage duration, meaning that they can't possibly be "stored on the stack". It is `s` that's "stored on the stack", but `"blah blah"` (if it exists as a separate object) is stored in static memory. – AnT stands with Russia Dec 14 '13 at 22:02
  • 2
    I'm treating this question as a [C] question, not a "what some compiler might do" question. Nowhere in the language specification it says that string literals only exist when they a pointed to. As far as the language is concerned, every string literal is a unnamed array object in static memory. As for what the optimizer might decide to do... it has absolutely nothing to with the language. In any case, the literal is either a) static or b) optimized out. In no case "stored on the stack" is the right answer. – AnT stands with Russia Dec 14 '13 at 22:07
  • Yeah, I obviously agree, by "blah blah" I meant the contents of `s`, since there is no other useful copy of that string to talk about. – Michał Trybus Dec 14 '13 at 22:09
  • 2
    Note also that string literals are not guaranteed the unique per-use address identity, meaning that the all identical literals used in different places in the code might share the same memory location. That makes it impossible to say whether this literal can possibly be optimized out. A pointer to it might exist somewhere else. Finally, I can image a compiler that would optimize out a 1- or 2-character literal, but a 10-character literal... no, compilers will not optimize it out. – AnT stands with Russia Dec 14 '13 at 22:10
  • Okay, that convinces me. – Michał Trybus Dec 14 '13 at 22:12
  • @AndreyT, just if you treat is as a [C] question, you just can't answer the question. Where it is stored it is completely up to the compiler, the standard doesn't say much. And you are wrong in your assumption that compilers will not optimize out long string literals. I just tested with gcc 4.7, it is capable of transforming long string literals into assembler immediates. – Jens Gustedt Dec 14 '13 at 22:25
  • @Jens Gustedt: That's great, but in the end it is a matter of what the OP was trying to ask about. In my experience, in 9 out of 10 cases "where is string literals stored" questions are really "how long a pointer to string literal is valid" questions in disguise. I could be wrong this time. Looking at the edits made to the original post (by a different person?) I'm not sure what this question is about anymore. – AnT stands with Russia Dec 14 '13 at 22:27
  • @AndreyT, I think OP's unknown intentions are the source of confusion here. I assumed it's one of those "can I modify `s`?" questions and did everything to show "yes, you can" without getting into the standard. After a while, I agree that what I answered is rather against the standard though. – Michał Trybus Dec 14 '13 at 22:34