When you do the #define
, there is not the compiler, but the preprocessor who replaces, textually, STRING0
with "string0" in the pre-processed source file, before passing it to the compiler proper.
The compiler never sees the STRING0, but only sees "string0" everywhere that you wrote STRING0.
edit:
Each instance of "string0" that replaces the STRING0 that you wrote in the source file is a string literals per se. If those string literals are guaranteed (or declared) as invariant, then the compiler might optimize memory allocation by storing a single copy of this "string0" and point other uses towards that copy (I rephrased this paragraph in edit).
(edit: those identical literal string constants might be merged into a singled copy, however this is is up to the compiler. THe standard does not require or enforce it: http://www.velocityreviews.com/forums/t946521-merging-of-string-literals-guaranteed-by-c-std.html )
As for your last question: the most portable is to declare those as: const char *
later edit: the best discussion about the string literals that I found so far is here: https://stackoverflow.com/a/2245983/1284631
Also, beware that a string literal can also appear in the initialization of statically-allocated char array, when it cannot be merged with other copies of it, since the content of the static array may be overwritten. See the example below, where the two identical string literals "hello" cannot be merged:
#include <stdio.h>
#include <string.h>
int main(){
char x[50]="hello";
printf("x=%s, &x[0]=%p\n",x,&x[0]);
const char *y="hello";
printf("y=%s, &y[0]=%p\n",y,&y[0]);
strcpy(&x[0],"zz");
printf("x=%s, &x[0]=%p\n",x,&x[0]);
return 0;
}
The output of this code is:
x=hello, &x[0]=0x7fff8a964370
y=hello, &y[0]=0x400714
x=zz, &x[0]=0x7fff8a964370