开发者

Unexpected result in C program

开发者 https://www.devze.com 2023-02-18 23:28 出处:网络
Can you please explain the output of this C program? I guess that the problem is with the stack getting corrupt during printf(\"%d\\n\",t);function call because I\'m pushing a float but reading an int

Can you please explain the output of this C program? I guess that the problem is with the stack getting corrupt during printf("%d\n",t); function call because I'm pushing a float but reading an int. I'm not sure.

#include <stdio.h>

int main() 
{ 
    long x; 
    float t; 
    scanf("%f",&t); 
    printf("%d\n",t); 
    x=30;
    printf("%f\n",x); 
    { 
        x=9;
        printf("%f\n",x); 
        { 
            x=10;
            printf("%f\n",x); 
        } 
        printf("%f\n",x); 
    } 
    x==9;
    printf("%f\n",x); 

}

And the output

$ ./a.out 
20.39
0
20.389999
20.389999
20.389999
20.389999
20.38999开发者_运维知识库9
$


What happens is that you lie to the compiler ... first you tell it you are going to send an int to printf but you send a float instead, and then you tell it you are going to send a double but you send a long instead.

Don't do that. Don't lie to the compiler.

You have invoked Undefined Behaviour. Anything can happen. Your program might corrupt the stack; it might output what you expect; it might make lemon juice come out of the USB port; it might make demons fly out of your nose; ...


You are using the wrong format specifier to print long. Use format specifier %ld instead. Results

printf("%f\n",x);
     // ^ change this to %ld 


What actually happens is:

  • Your float is 4 bytes, your long is 4 bytes, your double is 8 bytes.
  • You pass a float through ellipsis - it gets converted to a double. 8 bytes on stack.
  • You pass a long through ellipsis - 4 bytes on stack.
  • printf parses 8 bytes on stack (float specifier) as a double. This double will consist of the "important" part of the old double on stack, and a slight variation in the least significant part (your long).
  • Default %f output truncates the value, you don't see the variation.

Change all your %f to e.g. %.20f to see how the long affects the double.


printf("%d\n",t);

Using incorrect format specifier in printf invokes undefined behaviour.

Use %f for printing float and double and %ld for printing long

C99 clearly says (wrt printf and fprintf)

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

0

精彩评论

暂无评论...
验证码 换一张
取 消