Ahmed Yasen
Ahmed Yasen

Reputation: 145

What is the return value of &"suchString"?

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

Answers (2)

Keith Thompson
Keith Thompson

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

gsamaras
gsamaras

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

Related Questions