Why is this possible? (char * question, WIn32 related also)

Started by
6 comments, last by visitor 15 years, 10 months ago
Heya. So I was just wondering why the following is possible: char *pString = "Hello"; I mean, this is intuitive but I don't see how it works. Could I similarly do something like this? int *pArray = {91, 2, 65, 10, 43}; The reason I bring this up is that I've been doing some Win32 programming. I'm just filling out that WNDCLASSEX structure, like I've done zillions of times. The class name and menu name elements of the structure are LPCSTR's, which are just typedef'd character pointers. Like always, I've filled out this part of the structure like so: wc.lpszClassName = "myClass"; And it just hit me that I do not understand why this even compiles. I mean, what is the compiler doing with this? Is it just creating a static array on the stack and setting the char* to the address of the first element? It's weird that I've done this a zillion times and it never occurred to me until now to ask why. Oh well. There's always something new to learn about C++.
Advertisement
Quote:Original post by CDProp
I mean, what is the compiler doing with this? Is it just creating a static array on the stack and setting the char* to the address of the first element?

Pretty much... It's just magic ;)
It embeds the string-literal (array of characters) as a static buffer somewhere into your binary (not on the stack) and then assigns your char* variable to point at this static buffer.
If you compile your code and then open up the binary using a text editor, you should be able to find your string literals embedded in there somewhere.
That is awesome. Thank you very much.
Well, I had to log in and someone beat me to it, but I was going to say that also... the compiler creates what it calls a "literal pool" that gets thrown into the binary, as noted by hodgman. I just wanted to add the fact that those literals can be re-used... so if you do this...

char *a = "SomeString";
char *b = "SomeString";

... then a == b. It doesn't allocate twice. I'm pretty sure that's standard/defined behavior.

Oh cool. So is this how all literals of all types are handled? Like, if I just had a line that said:

int x = 5;

Does the number 5 get stored somewhere in the binary? Or is this just for string literals? Also, would the int array example I posted above work?

Damn, this is the good stuff, imo.
Well, an integer would just get stored as part of a store instruction (mov, etc). There isn't much use in pooling those, because the literal itself can be one of the operands of the instruction.

For your example, there would be a "mov x, 5", as binary, stored somewhere in the code segment somewhere.

EDIT: I just wanted to include the fact that I'm just speaking in generalities. I'm sure there are clever reasons to pool other types of literals. Compilers are so complicated these days I have no idea if they do or why.
Quote:CDProp:
Oh cool. So is this how all literals of all types are handled?
What, string pooling? No.

Quote:Does the number 5 get stored somewhere in the binary
Somewhere along the way, there has be one or more instructions that stores the number 5. But you can’t “store” a string like you would an integer. You can place the string somewhere in memory, though, and then operate on the memory location.

Quote:Also, would the int array example I posted above work?
No. Especially since you don’t have an integer array, you have an integer pointer.

Quote:Smitty:
I'm sure there are clever reasons to pool other types of literals
Yeah, but that’s not ordinary storing a value in a variable. You might have a specialized pool for something like a lookup table, but at that point you’re doing something conceptually different.
On a different note, it is important to know that this shouldn't be possible and it is a glitch in the language to allow it.

The string literal is unmodifiable and therefore you should write
const char* str = "hello";

to avoid making stupid mistakes such as
char* str = "hello";strcat(str, " world"); //has a very good chance to crash


(I see, though, that in C using const char* instead only produces a warning with strcat whereas in C++ it will result in a compiler error.)

This topic is closed to new replies.

Advertisement