Reputation: 145
The output of this snippet of code:
char* str1 = "suchString";
printf("%s %s\n", &"suchString", &str1);
is:
suchString �WO:+(or any unknown symbols)
What is the difference and why the output not the same?
EDIT If you trying to eliminate the & operator as follows:
char* str1 = "suchString";
printf("%s %s\n", "suchString", &str1);
The output is the same of the first snippet of code. Now, is how the "suchString" is the same of &"suchString"?
Upvotes: 0
Views: 107
Reputation: 263237
char* str1 = "suchString";
printf("%s %s\n", &"suchString", &str1);
The %s
specifier requires an argument of type char*
, which must be a pointer to a string. You've provided arguments of types char (*)[11]
and char**
. Your code has undefined behavior, which means that in principle it could do literally anything.
A string literal is an array. The address of an array refers to the same memory location as the address of the array's first element, but it's of a different type. Passing just "suchString"
as the second argument would be correct, since the array "decays" to a pointer to its first element.
In an implementation where all pointers have the same representation (which is typical but not required), passing a pointer to the same memory location but with the wrong type is likely to "work". printf
is special in that it can accept arguments of different types, so the compiler can't necessarily diagnose type errors. For a non-variadic function, an error like this would probably be rejected at compile time.
str1
is a pointer, not an array. You've initialized it to point to the initial character of the string literal. You could pass str1
to printf
, but &str1
is the address of a pointer object, which is not only of the wrong type, but doesn't point to a string at all. Thus the output is garbage.
If you want to print the string values, you can do this:
const char* str1 = "suchString";
printf("%s %s\n", "suchString", str1);
(I've added const
so the compiler will complain if you try to modify the contents of the string literal.)
Upvotes: 1
Reputation: 73366
This:
&"suchString"
takes the address of a string literal. String literals are arrays, not pointers.
Had you compiled with warnings enabled, you had knew already:
prog.c:5:14: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[11]' [-Wformat=]
printf("%s %s\n", &"suchString", &str1);
~^ ~~~~~~~~~~~~~
prog.c:5:17: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char **' [-Wformat=]
printf("%s %s\n", &"suchString", &str1);
~^ ~~~~~
The first is of type char (*)[11]
, while the second is of type char **
.
As for the garbage values, you are providing an address of a pointer to %s
format, thus ruining the print. If you used %p
instead, you would see an address being printed out, e.g. "0x7ffe676f5588".
Same goes for when attempting to print the address of the string literal, with the string specifier in printf()
.
Moreover, you should cast to void*
, like this:
printf("%p %p\n", (void*)"suchString", (void*)str1);
Upvotes: 3