strange output while printing float as integer and integer as float in C [duplicate]

夙愿已清 提交于 2020-06-23 07:29:29

问题


the following code is not showing the expected output which is garbage value ( strangely the values are swapped )

#include<stdio.h>
int main()
{
    float f = 4.6;
    int d = 7;
    printf("%d %f\n",f,d);
    return 0;
}

output: 7 4.600000


回答1:


Let's reduce this a bit:

float f = 4.6;
printf("%d\n", f);

That's undefined behavior. The correct format specifier must be given an argument of the correct type.

Undefined behavior can cause any outcome, including this odd outcome that you are seeing.

Further thoughts:

Now, you might be asking why a compiler would even produce this code. So let's look at the x86-64 assembly for 2 codes:

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

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

Other than the format string, these two codes produce identical assembly. This is likely because the calling convention requires floats to be placed in different registers than integers, or that floats should be passed on the stack (or any number of other rules that handle floats and integers differently).

This should make it clearer why the code you posted is still producing something useful, even though the code is just broken.




回答2:


The argument corresponding to %d must be an int, and the argument corresponding to %f must be a double. Arguments to variadic functions undergo some standard conversions (so float will be converted to double automatically), but they're not automatically converted to the appropriate types for their corresponding printf format specifiers.




回答3:


Not really hard to understand. The float value is passed in float registers, while the int value is passed in the conventional parameter stack. So when the values are referenced, they are fetched from different areas and it magically works, even though is shouldn't (and won't, on a different box).




回答4:


For example, gcc 4.7.2 for amd64 does this, because integer and floating-point arguments are passed in different registers. This effectively reorders the arguments.

From "System V Application Binary Interface. AMD64 Architecture Processor Supplement. Draft Version 0.99.6" (floating-point numbers have class SSE):

  1. If the class is INTEGER, the next available register of the sequence %rdi,%rsi, %rdx, %rcx, %r8 and %r9 is used.
  2. If the class is SSE, the next available vector register is used, the registers are taken in the order from %xmm0 to %xmm7.

Of course you should not do this and enable warnings to catch it during compilation.



来源:https://stackoverflow.com/questions/25535507/strange-output-while-printing-float-as-integer-and-integer-as-float-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!