Anúncio

No More Noprototype Function

4 de Jul de 2016
Anúncio

Mais conteúdo relacionado

Anúncio

Último(20)

No More Noprototype Function

  1. No More “No prototype function” 2016/7/2 @simotin13
  2. ・@simotin13 Hiroyuki Miyazaki ・大阪で主に組み込みとかの仕事してます。 ・Rubyが好きです。 ・RubyでC言語のコンパイラ作ろうと思って勉強中です。 ・本日お集まりの皆様のお口に合うようなレベルの高い話ではないですが、大阪から来たので何か 爪痕を残して帰りたいと思います。どうか軽い気持ちで聞いてください。 自己紹介
  3. サンプルコード
  4. main.c #include <stdio.h> int main(int argc, char **argv) { if (hoge() == 1) { // 無問題 printf(“One!!!¥n”); } else { // どうかしてるぜ!!! printf(“Not One!!!¥n”); } return 0; }
  5. hoge.c unsigned char hoge(void) { return 1; }
  6. ビルド $gcc main.c hoge.c -Wall main.c: In function 'main': main.c:5:2: warning: implicit declaration of function 'hoge' [-Wimplicit-function-declaration] if (hoge() == 1) { ^ $
  7. げげっ! ワーニング出てるやん。
  8. なになに、 “implicit declaration” ・・・ う~ん・・
  9. おぉ! hogeのプロトタイプ宣言忘れてたわ。
  10. プロトタイプ宣言を追加 #include <stdio.h> // ★ ↓プロトタイプ宣言追加 extern unsigned char hoge(void); int main(int argc, char **argv) { if (hoge() == 1) { // 無問題 printf(“One!¥n”); } else { // どうかしてるぜ!!! printf(“Not One!¥n”); } return 0; }
  11. 再度、ビルド $gcc main.c hoge.c -Wall $
  12. よしよし!問題ない。 動かしてみるか!
  13. 実行 $ ./a.out One!!!
  14. 「安心してください。 動きますよ!」
  15. ここからが、本題。
  16. 「もしも新人プログラマーが ビルド時に 『-Wall』 をつけなかったら」
  17. ビルド $gcc main.c hoge.c $
  18. おぉ! 問題なくビルドできた! よかったよかった。
  19. さて、動かしてみますか!
  20. 実行 $ ./a.out One!!!
  21. 「安心しないでください! 動かない可能性がありますよ。」
  22. 「でも動いてるじゃん」 だって!?
  23. その証拠に・・・ これでもくらえ!
  24. 最適化ビルド $gcc main.c hoge.c -Os $
  25. 実行 $ ./a.out Not One!!!
  26. えぇ!? このコンパイラどうかしてるぜ!
  27. 最適化なし逆汗 08048630 <hoge>: 8048630: 55 push ebp 8048631: 89 e5 mov ebp,esp 8048633: b8 01 00 00 00 mov eax,0x1 8048638: 5d pop ebp 8048639: c3 ret
  28. (サイズ)最適化あり逆汗 0804863c <hoge>: 804863c: 55 push ebp 804863d: b0 01 mov al,0x1 804863f: 89 e5 mov ebp,esp 8048641: 5d pop ebp 8048642: c3 ret
  29. マシン語比較 0804863c <hoge>: 804863c: 55 push ebp 804863d: b0 01 mov al,0x1 804863f: 89 e5 mov ebp,esp 8048641: 5d pop ebp 8048642: c3 ret 08048630 <hoge>: 8048630: 55 push ebp 8048631: 89 e5 mov ebp,esp 8048633: b8 01 00 00 00 mov eax,0x1 8048638: 5d pop ebp 8048639: c3 ret 最適化なし サイズ最適化
  30. おぉ! 確かに3バイトもサイズが小さく なってる
  31. 呼び出し側(main.c) ~ プロトタイプ宣言なし~ 080485fc <main>: 80485fc: 55 push ebp 80485fd: 89 e5 mov ebp,esp 80485ff: 83 e4 f0 and esp,0xfffffff0 8048602: 83 ec 10 sub esp,0x10 8048605: e8 26 00 00 00 call 8048630 <hoge> 804860a: 83 f8 01 cmp eax,0x1 804860d: 75 0e jne 804861d <main+0x21>
  32. 呼び出し側(main.c) ~ プロトタイプ宣言あり~ 080485fc <main>: 80485fc: 55 push ebp 80485fd: 89 e5 mov ebp,esp 80485ff: 83 e4 f0 and esp,0xfffffff0 8048602: 83 ec 10 sub esp,0x10 8048605: e8 25 00 00 00 call 804862f <hoge> 804860a: 3c 01 cmp al,0x1 804860c: 75 0e jne 804861c <main+0x20>
  33. プロトタイプ宣言ありだと きっちりALレジスタで比較してる
  34. ・ 結論
  35. No More ! “No prototype function” ※-Wall は忘れずにね。
  36. ・バイナリフォーマットにシンボルだけじゃなく て関数のシグネチャ持たせれば、プロトタイプ宣 言いらないんじゃね?(戻り値のサイズの不一致と かリンク時に検出できないかしら) ~素朴な疑問~
Anúncio