もちろん、フォーマットに対応しない引数を渡すことは未定義の動作であるため、言語は出力が変更される理由を教えてくれません。実装、それが生成するコード、そして場合によってはオペレーティングシステムも確認する必要があります。
私の設定はあなたの設定とは異なります、
Linux3.1.10-1.16-デスクトップx86_64GNU/ Linux(openSuSE 12.1)
gcc-4.6.2を使用。しかし、それは十分に類似しているので、同じメカニズムを疑うのは合理的です。
生成されたアセンブリ(-O3
、習慣から)を見ると、関連する部分(main
)は次のようになります。
.cfi_startproc
subq $8, %rsp # adjust stack pointer
.cfi_def_cfa_offset 16
movl $.LC1, %edi # move format string to edi
movl $1, %eax # move 1 to eax, seems to be the number of double arguments
movsd .LC0(%rip), %xmm0 # move the double to the floating point register
call printf
xorl %eax, %eax # clear eax (return 0)
addq $8, %rsp # adjust stack pointer
.cfi_def_cfa_offset 8
ret # return
の代わりにdouble
、私が渡す場合int
、あまり変更はありませんが、それは大幅に
movl $47, %esi # move int to esi
movl $.LC0, %edi # format string
xorl %eax, %eax # clear eax
call printf
に渡される引数のタイプと数の多くのバリエーションについて生成されたコードを調べました。printf
一貫して、最初のdouble
(またはプロモートさfloat
れた)引数は、で渡されxmmN
、N = 0, 1, 2
整数(int
、、、、符号char
にlong
関係なく)は、、で渡されesi
ますedx
。ecx
、、r8d
そしてr9d
スタック。
だから私printf
はで発表さint
れたものを探し、esi
そこに起こったことは何でも印刷するという推測に挑戦します。
そこに何も動かされていないときに、の内容がesi
何らかの形で予測可能であるかどうかmain
、そしてそれらが何を意味するのか、私にはわかりません。