c programming printf format searches expressions

前端 未结 3 832
执念已碎
执念已碎 2021-01-24 22:40

I have a small question. I have this piece of code:

#include 

int main(){
    printf(\"%d, %f, %d\\n\", 0.9, 10, \'C\');
}

And

3条回答
  •  隐瞒了意图╮
    2021-01-24 22:43

    But I would have expected: …

    When the format string does not match the types of the arguments in order, the behavior is undefined. Anything can happen. You cannot expect anything (and I do not see why you would expect 0. Maybe you expect printf to use the format string to convert the arguments between floating-point and integer. It just doesn't. It's a variadic function like you could write your own, and the fact that the format string encodes the types of the trailing arguments is not used to convert them).

    Modern calling conventions use registers for the first few arguments, and can use registers even for variadic functions. On x86-64, the convention can be for instance that the first floating-point argument to a variadic function can always be expected in the floating-point register xmm0, whereas integer arguments are passed in general-purpose registers %rdi, %rsi, %rdx, … This has the effect that printf("%f %d", 1, 1.0) prints the floating-point argument followed by the integer argument.

    As an illustration, here is a short program:

    #include 
    
    int main(){
      printf("%d, %f, %d\n", 0.9, 10, 'C');
    
      printf("%d, %f, %d\n", 10, 0.9, 'C');
    }
    

    This is how my compiler (Clang on Mac OS X 10.6) compiles the program:

    leaq , %rbx
    
    movq    %rbx, %rdi
    movsd   , %xmm0
    movl    $10, %esi
    movl    $67, %edx
    movb    $1, %al
    callq   _printf
    
    movq    %rbx, %rdi
    movl    $10, %esi
    movsd   , %xmm0
    movl    $67, %edx
    movb    $1, %al
    callq   _printf
    
    …
    

    It is clear that the two calls produce the same result. But in the case of one, it is accidental and only “works” for this particular compiler version and ABI, whereas the other one respects the standard and has to work anywhere.

    Again, printf("%d %f", 0.9, 10) is undefined behavior and you should not use it in any circumstances.

提交回复
热议问题