5
votes

Why does this work? (i.e how is passing int to printf() results in printing the string)

#include<stdio.h>

int main() {
    int n="String";
    printf("%s",n);
    return 0;
}

warning: initialization makes integer from pointer without a cast [enabled by default]
int n="String";
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s",n);

Output:String

compiler:gcc 4.8.5

4

4 Answers

8
votes

In your code,

  int n="String";  //conversion of pointer to integer

is highly-implementation dependent note 1

and

 printf("%s",n);   //passing incompatible type of argument

invokes undefined behavior. note 2Don't do that.

Moral of the story: The warnings are there for a reason, pay heed to them.


Note 1:

Quoting C11, chapter §6.3.2.3

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. [....]

Note 2:

chapter §7.21.6.1

[....] If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

and for the type of argument for %s format specifier with printf()

s If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type. [...]

5
votes

The behaviour of your program is undefined.

Essentially, you're assigning a const char* to an int, and the printf converts it back. But do regard that as entirely coincidental: you're not allowed to cast unrelated types like that.

C gives you the ability to shoot yourself in the foot.

1
votes

int type can store 4 bytes numbers on most today's computers (from -2147483647 to 2147483647)

Which means it ""can"" store SOME address as well, only problem is when your address is bigger than 2147483647 it will cause overflow and you will not be able to get the address, (which is very bad for your program obviously)

An address is a number referring to memory space, Pointers are made to store addresses, they are larger (8 bytes on 64bits systems, 4 bytes on 32bits systems) and they are also unsigned (only positive)

which means, when you affect int n="String"; if the address to "String" is under 2147483647 it wont cause issues and you code will run (DONT DO THAT)

http://www.tutorialspoint.com/c_standard_library/limits_h.htm

now if you think about it, you can guess why there is a 4GB ram limit on 32bit systems

(sorry about possible english mistakes, I m french)

0
votes

Compiling with options like -Wall -Wextra -Werror -Wint-to-pointer-cast -pedantic (GCC) will show you very quickly that this behaviour should not be relied upon.