[c++] How does this program work?



Answers

Technically speaking there is no the printf, each library implements its own, and therefore, your method of trying to study printf's behavior by doing what you are doing is not going to be of much use. You could be trying to study the behavior of printf on your system, and if so, you should read the documentation, and look at the source code for printf if it is available for your library.

For example, on my Macbook, I get the output 1606416304 with your program.

Having said that, when you pass a float to a variadic function, the float is passed as a double. So, your program is equivalent to having declared a as a double.

To examine the bytes of a double, you can see this answer to a recent question here on SO.

Let's do that:

#include <stdio.h>

int main(void)
{
    double a = 1234.5f;
    unsigned char *p = (unsigned char *)&a;
    size_t i;

    printf("size of double: %zu, int: %zu\n", sizeof(double), sizeof(int));
    for (i=0; i < sizeof a; ++i)
        printf("%02x ", p[i]);
    putchar('\n');
    return 0;
}

When I run the above program, I get:

size of double: 8, int: 4
00 00 00 00 00 4a 93 40 

So, the first four bytes of the double turned out to be 0, which may be why you got 0 as the output of your printf call.

For more interesting results, we can change the program a bit:

#include <stdio.h>

int main(void)
{
    double a = 1234.5f;
    int b = 42;

    printf("%d %d\n", a, b);
    return 0;
}

When I run the above program on my Macbook, I get:

42 1606416384

With the same program on a Linux machine, I get:

0 1083394560
Question
#include <stdio.h>

int main() {
    float a = 1234.5f;
    printf("%d\n", a);
    return 0;
}

It displays a 0!! How is that possible? What is the reasoning?


I have deliberately put a %d in the printf statement to study the behaviour of printf.




hey it had to print something so it printed a 0. Remember in C 0 is everything else!




You just need to use the appropriate format specifier (%d,%f,%s,etc.) with the relevant data type (int,float, string, etc.).




Since you tagged it with C++ as well, this code does the conversion as you probably expect:

#include <iostream.h>

int main() {
    float a = 1234.5f;
    std::cout << a << " " << (int)a << "\n";
    return 0;
}

Output:

1234.5 1234



The reason is that printf() is a pretty dumb function. It does not check types at all. If you say the first argument is an int (and this is what you are saying with %d), it believes you and it takes just the bytes needed for an int. In this case, asuming your machine uses four-byte int and eight-byte double (the float is converted to a double inside printf()), the first four bytes of a will be just zeroes, and this gets printed.




Because you invoked undefined behaviour: you violated the contract of the printf() method by lying to it about its parameter types, so the compiler is free to do whatever it pleases. It could make the program output "dksjalk is a ninnyhead!!!" and technically it would still be right.




Links