The code is legal in C. It just may not produce the result you expected.
The type of string literal is char[N]
in C and const char[N]
in C++, where N is the number of characters in the string literal.
"foo"
is type char[4]
and const char[4]
in C and C++ respectively. Basically it's an array. An array gets converted into a pointer to its first element when used in an expression. So in the comparison, if("foo" == "foo")
the string literals get converted into pointers. Hence, the "address comparison".
In the comparison,
if("foo" == "foo"){
the addresses of the string literals are compared, which may or may not be equal.
It is equivalent to:
const char *p = "foo";
const char *q = "foo";
if ( p == q) {
...
}
C standard doesn't guarantee that addresses are equal for two string literals with same content ("foo"
's here) are placed in same location. But in practice, any compiler would place at the same address. So the comparison seems to work. But you can't rely on this behaviour.
6.4.5, String literals (C11, draft)
It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Similarly, this comparison
if("foo" == "bob"){
...
}
is equivalent to:
const char *x = "foo";
const char *y = "bob";
if("foo" == "bob"){
...
}
In this case, the string literals would be at different locations and pointer comparison fails. So in both cases, it looks as if the ==
operator actually works for comparing C-strings.
Instead if you do comparisons using arrays, it will not work:
char s1[] ="foo";
char s2[] = "foo";
if (s1 == s2) {
/* always false */
}
The difference is that when an array is initialized with a string literals, it's copied into the array. The arrays s1
and s2
have distinct the addresses and will never be equal. But in case of string literals, both p
and q
point to the same address (assuming the compiler places so - this is not guaranteed as noted above).