Yabu.log

ITなどの雑記

C言語復習その6。プリプロセッサ、リンカについて

本書ラストのライブラリまで行けると思ったが、時間がなくなった。 もっと有意義に3連休を過ごせなかったのだろうか。(反省)

プログラミング学習シリーズ C言語改訂版 2 はじめて学ぶCの仕組み

プログラミング学習シリーズ C言語改訂版 2 はじめて学ぶCの仕組み

ソースコードから実行ファイル(exe,elf)などができるまで

の処理で処理される。

  • コンパイラは自動的に1,3の処理を呼んでいる
  • 本書の想定だとそれぞれcpp.exe,gcc.exe,ld.exeを使っているようだ
  • cppってC++用のコンパイラだと思っていたのだが...
    • C Preprocessorの略らしい

プリプロセッサ

  • #ハッシュで始まる行を対象に処理をする仕組み

    • #defineで定義されている固定値を置き換える
  • gccでは-Eオプションで実行することにより、プリプロセッサの結果を標準入出力に表示できる

元ソース

#include<stdio.h>
//defineで値を定義
#define bignumber 1000

//マクロを定義
#define max(a,b) (a >b)? a: b

int main(){
  int a = bignumber;
  printf("%d is larger\n", max(100,10));
  printf("%d\n",a);
  printf("%d\n",bignumber);
}

gcc -Eの出力(※stdio.hの展開が巨大すぎるのでそれは略している)

・・・(stdio.hの展開略)

int main(){
  int a = 1000;
  printf("%d is larger\n", (100 >10)? 100: 10);
  printf("%d\n",a);
  printf("%d\n",1000);
}
  • マクロの注意点
    • 関数と違って「型」の情報がない
    • 演算子の優先順位でハマる可能性がある
    • 例えば
int a=5,b=4;
printf("%d\n",max(a, ++b));//6が表示される
int a=5,b=4;
printf("%d\n",(a >++b)? a: ++b);
  • 例2:以下は大きい方に+100された値を期待しているが。。。
    • printf("larger + 100=%d\n",max(20,10)+100);のソースが
    • printf("larger + 100=%d\n",(20 >10)? 20: 10 +100);と展開される
      • この3項演算子(20>10)?10:110となるため評価結果は20となる
    • 出力結果はlarger + 100=20となる。
  • undef#defineで定義した値を取り下げる
# define max 5
printf("%d\n",max);
# undef max
#define max 10
printf("%d\n",max);
- `gcc -E`で以下のように展開される
printf("%d\n",5);


printf("%d\n",10);
  • ifdefでdefineの定義に応じてコードを切り替えられる
    • 昔nmapのソースを読もうと思ったことがあったが、コードに#ifdef DEBUGみたいなのを散見した
    • 多分テストやデバッグ時のコードをプロダクションのバイナリに含まされなくない、というようなことをやっている
  • 組み込みマクロというものもある。
    • コンパイラ?ライブラリ?にあらかじめ用意されている
      • ソースprintf("%s:%d:%s\n",__FILE__,__LINE__,__func__);
      • プリプロセッサ適応後printf("%s:%d:%s\n","chap6/preprocesser.c",39,__func__);
      • 実行結果chap6/preprocesser.c:39:main
        • 正確には__func__はマクロではなく前定義識別名というらしい

リンカ

  • ソース -> 実行ファイルの変換の大トリのやつ。
  • コンパイラ.cファイルから.oファイルにコンパイルするところまでしかやらない。
  • 実際に.oを組み合わせて実行ファイルを作っているのはリンカ。
  • .oファイルは実行ファイル作成時に消されてしまう。
    • gcc に-cオプションをつけることで、リンカの処理を実行しないようにできる

リンカ適応度前適応後のバイナリを比べてみる

  • gcc test.c a.c b.c -o test
  • gcc -c test.c a.c b.c
$ ls -alt
total 72
-rw-r--r--  1   staff   748  7 16 19:13 b.o
-rw-r--r--  1   staff   748  7 16 19:13 a.o
-rw-r--r--  1   staff   672  7 16 19:13 test.o
-rwxr-xr-x  1   staff  8488  7 16 19:13 test
  • test.o:8488Byteのサイズはa.o + b.o + test.o = 2168Byteを大きくうわ待っている
$ hexdump -C test
00000000  cf fa ed fe 07 00 00 01  03 00 00 80 02 00 00 00  |................|
00000010  0f 00 00 00 b0 04 00 00  85 00 20 00 00 00 00 00  |.......... .....|
00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
00000040  00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  19 00 00 00 d8 01 00 00  |................|
00000070  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
00000080  00 00 00 00 01 00 00 00  00 10 00 00 00 00 00 00  |................|
00000090  00 00 00 00 00 00 00 00  00 10 00 00 00 00 00 00  |................|
000000a0  07 00 00 00 05 00 00 00  05 00 00 00 00 00 00 00  |................|
000000b0  5f 5f 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |__text..........|
000000c0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
000000d0  20 0f 00 00 01 00 00 00  5d 00 00 00 00 00 00 00  | .......].......|
000000e0  20 0f 00 00 04 00 00 00  00 00 00 00 00 00 00 00  | ...............|
000000f0  00 04 00 80 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000100  5f 5f 73 74 75 62 73 00  00 00 00 00 00 00 00 00  |__stubs.........|
00000110  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
00000120  7e 0f 00 00 01 00 00 00  06 00 00 00 00 00 00 00  |~...............|
00000130  7e 0f 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |~...............|
00000140  08 04 00 80 00 00 00 00  06 00 00 00 00 00 00 00  |................|
00000150  5f 5f 73 74 75 62 5f 68  65 6c 70 65 72 00 00 00  |__stub_helper...|
00000160  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
00000170  84 0f 00 00 01 00 00 00  1a 00 00 00 00 00 00 00  |................|
00000180  84 0f 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
00000190  00 04 00 80 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001a0  5f 5f 63 73 74 72 69 6e  67 00 00 00 00 00 00 00  |__cstring.......|
000001b0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
000001c0  9e 0f 00 00 01 00 00 00  14 00 00 00 00 00 00 00  |................|
000001d0  9e 0f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001e0  02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001f0  5f 5f 75 6e 77 69 6e 64  5f 69 6e 66 6f 00 00 00  |__unwind_info...|
00000200  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
00000210  b4 0f 00 00 01 00 00 00  48 00 00 00 00 00 00 00  |........H.......|
00000220  b4 0f 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
00000230  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000240  19 00 00 00 e8 00 00 00  5f 5f 44 41 54 41 00 00  |........__DATA..|
00000250  00 00 00 00 00 00 00 00  00 10 00 00 01 00 00 00  |................|
00000260  00 10 00 00 00 00 00 00  00 10 00 00 00 00 00 00  |................|
00000270  00 10 00 00 00 00 00 00  07 00 00 00 03 00 00 00  |................|
00000280  02 00 00 00 00 00 00 00  5f 5f 6e 6c 5f 73 79 6d  |........__nl_sym|
00000290  62 6f 6c 5f 70 74 72 00  5f 5f 44 41 54 41 00 00  |bol_ptr.__DATA..|
000002a0  00 00 00 00 00 00 00 00  00 10 00 00 01 00 00 00  |................|
000002b0  10 00 00 00 00 00 00 00  00 10 00 00 03 00 00 00  |................|
000002c0  00 00 00 00 00 00 00 00  06 00 00 00 01 00 00 00  |................|
000002d0  00 00 00 00 00 00 00 00  5f 5f 6c 61 5f 73 79 6d  |........__la_sym|
000002e0  62 6f 6c 5f 70 74 72 00  5f 5f 44 41 54 41 00 00  |bol_ptr.__DATA..|
000002f0  00 00 00 00 00 00 00 00  10 10 00 00 01 00 00 00  |................|
00000300  08 00 00 00 00 00 00 00  10 10 00 00 03 00 00 00  |................|
00000310  00 00 00 00 00 00 00 00  07 00 00 00 03 00 00 00  |................|
00000320  00 00 00 00 00 00 00 00  19 00 00 00 48 00 00 00  |............H...|
00000330  5f 5f 4c 49 4e 4b 45 44  49 54 00 00 00 00 00 00  |__LINKEDIT......|
00000340  00 20 00 00 01 00 00 00  00 10 00 00 00 00 00 00  |. ..............|
00000350  00 20 00 00 00 00 00 00  28 01 00 00 00 00 00 00  |. ......(.......|
00000360  07 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000370  22 00 00 80 30 00 00 00  00 20 00 00 08 00 00 00  |"...0.... ......|
00000380  08 20 00 00 18 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
00000390  20 20 00 00 10 00 00 00  30 20 00 00 40 00 00 00  |  ......0 ..@...|
000003a0  02 00 00 00 18 00 00 00  78 20 00 00 06 00 00 00  |........x ......|
000003b0  e8 20 00 00 40 00 00 00  0b 00 00 00 50 00 00 00  |. ..@.......P...|
000003c0  00 00 00 00 00 00 00 00  00 00 00 00 04 00 00 00  |................|
000003d0  04 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
000003e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000003f0  d8 20 00 00 04 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
00000400  00 00 00 00 00 00 00 00  0e 00 00 00 20 00 00 00  |............ ...|
00000410  0c 00 00 00 2f 75 73 72  2f 6c 69 62 2f 64 79 6c  |..../usr/lib/dyl|
00000420  64 00 00 00 00 00 00 00  1b 00 00 00 18 00 00 00  |d...............|
00000430  01 a0 6d a0 dc d8 3b 93  b9 e4 c3 d8 18 65 02 c8  |..m...;......e..|
00000440  24 00 00 00 10 00 00 00  00 0d 0a 00 00 0d 0a 00  |$...............|
00000450  2a 00 00 00 10 00 00 00  00 00 00 00 00 00 00 00  |*...............|
00000460  28 00 00 80 18 00 00 00  20 0f 00 00 00 00 00 00  |(....... .......|
00000470  00 00 00 00 00 00 00 00  0c 00 00 00 38 00 00 00  |............8...|
00000480  18 00 00 00 02 00 00 00  04 32 e4 04 00 00 01 00  |.........2......|
00000490  2f 75 73 72 2f 6c 69 62  2f 6c 69 62 53 79 73 74  |/usr/lib/libSyst|
000004a0  65 6d 2e 42 2e 64 79 6c  69 62 00 00 00 00 00 00  |em.B.dylib......|
000004b0  26 00 00 00 10 00 00 00  70 20 00 00 08 00 00 00  |&.......p ......|
000004c0  29 00 00 00 10 00 00 00  78 20 00 00 00 00 00 00  |).......x ......|
000004d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000f20  55 48 89 e5 b0 00 e8 15  00 00 00 b0 00 e8 2e 00  |UH..............|
00000f30  00 00 31 c0 5d c3 90 90  90 90 90 90 90 90 90 90  |..1.]...........|
00000f40  55 48 89 e5 48 83 ec 10  48 8d 3d 4f 00 00 00 e8  |UH..H...H.=O....|
00000f50  2a 00 00 00 89 45 fc 48  83 c4 10 5d c3 90 90 90  |*....E.H...]....|
00000f60  55 48 89 e5 48 83 ec 10  48 8d 3d 38 00 00 00 e8  |UH..H...H.=8....|
00000f70  0a 00 00 00 89 45 fc 48  83 c4 10 5d c3 90 ff 25  |.....E.H...]...%|
00000f80  8c 00 00 00 4c 8d 1d 7d  00 00 00 41 53 ff 25 6d  |....L..}...AS.%m|
00000f90  00 00 00 90 68 00 00 00  00 e9 e6 ff ff ff 61 20  |....h.........a |
00000fa0  63 61 6c 6c 65 64 00 62  28 29 20 63 61 6c 6c 65  |called.b() calle|
00000fb0  64 00 00 00 01 00 00 00  1c 00 00 00 00 00 00 00  |d...............|
00000fc0  1c 00 00 00 00 00 00 00  1c 00 00 00 02 00 00 00  |................|
00000fd0  20 0f 00 00 34 00 00 00  34 00 00 00 7e 0f 00 00  | ...4...4...~...|
00000fe0  00 00 00 00 34 00 00 00  03 00 00 00 0c 00 01 00  |....4...........|
00000ff0  10 00 01 00 00 00 00 00  00 00 00 01 00 00 00 00  |................|
00001000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00001010  94 0f 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00001020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002000  11 22 10 51 00 00 00 00  11 40 64 79 6c 64 5f 73  |.".Q.....@dyld_s|
00002010  74 75 62 5f 62 69 6e 64  65 72 00 51 72 00 90 00  |tub_binder.Qr...|
00002020  72 10 11 40 5f 70 75 74  73 00 90 00 00 00 00 00  |r..@_puts.......|
00002030  00 01 5f 00 05 00 04 5f  6d 68 5f 65 78 65 63 75  |.._...._mh_execu|
00002040  74 65 5f 68 65 61 64 65  72 00 27 6d 61 69 6e 00  |te_header.'main.|
00002050  2b 61 00 30 62 00 35 02  00 00 00 03 00 a0 1e 00  |+a.0b.5.........|
00002060  03 00 c0 1e 00 03 00 e0  1e 00 00 00 00 00 00 00  |................|
00002070  a0 1e 20 20 00 00 00 00  02 00 00 00 0f 01 10 00  |..  ............|
00002080  00 00 00 00 01 00 00 00  16 00 00 00 0f 01 00 00  |................|
00002090  40 0f 00 00 01 00 00 00  19 00 00 00 0f 01 00 00  |@...............|
000020a0  60 0f 00 00 01 00 00 00  1c 00 00 00 0f 01 00 00  |`...............|
000020b0  20 0f 00 00 01 00 00 00  22 00 00 00 01 00 00 01  | .......".......|
000020c0  00 00 00 00 00 00 00 00  28 00 00 00 01 00 00 01  |........(.......|
000020d0  00 00 00 00 00 00 00 00  04 00 00 00 05 00 00 00  |................|
000020e0  00 00 00 40 04 00 00 00  20 00 5f 5f 6d 68 5f 65  |...@.... .__mh_e|
000020f0  78 65 63 75 74 65 5f 68  65 61 64 65 72 00 5f 61  |xecute_header._a|
00002100  00 5f 62 00 5f 6d 61 69  6e 00 5f 70 75 74 73 00  |._b._main._puts.|
00002110  64 79 6c 64 5f 73 74 75  62 5f 62 69 6e 64 65 72  |dyld_stub_binder|
00002120  00 00 00 00 00 00 00 00                           |........|
$ hexdump -C test.o
00000000  cf fa ed fe 07 00 00 01  03 00 00 00 01 00 00 00  |................|
00000010  04 00 00 00 b0 01 00 00  00 20 00 00 00 00 00 00  |......... ......|
00000020  19 00 00 00 38 01 00 00  00 00 00 00 00 00 00 00  |....8...........|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  78 00 00 00 00 00 00 00  d0 01 00 00 00 00 00 00  |x...............|
00000050  78 00 00 00 00 00 00 00  07 00 00 00 07 00 00 00  |x...............|
00000060  03 00 00 00 00 00 00 00  5f 5f 74 65 78 74 00 00  |........__text..|
00000070  00 00 00 00 00 00 00 00  5f 5f 54 45 58 54 00 00  |........__TEXT..|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  16 00 00 00 00 00 00 00  d0 01 00 00 04 00 00 00  |................|
000000a0  48 02 00 00 02 00 00 00  00 04 00 80 00 00 00 00  |H...............|
000000b0  00 00 00 00 00 00 00 00  5f 5f 63 6f 6d 70 61 63  |........__compac|
000000c0  74 5f 75 6e 77 69 6e 64  5f 5f 4c 44 00 00 00 00  |t_unwind__LD....|
000000d0  00 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
000000e0  20 00 00 00 00 00 00 00  e8 01 00 00 03 00 00 00  | ...............|
000000f0  58 02 00 00 01 00 00 00  00 00 00 02 00 00 00 00  |X...............|
00000100  00 00 00 00 00 00 00 00  5f 5f 65 68 5f 66 72 61  |........__eh_fra|
00000110  6d 65 00 00 00 00 00 00  5f 5f 54 45 58 54 00 00  |me......__TEXT..|
00000120  00 00 00 00 00 00 00 00  38 00 00 00 00 00 00 00  |........8.......|
00000130  40 00 00 00 00 00 00 00  08 02 00 00 03 00 00 00  |@...............|
00000140  00 00 00 00 00 00 00 00  0b 00 00 68 00 00 00 00  |...........h....|
00000150  00 00 00 00 00 00 00 00  24 00 00 00 10 00 00 00  |........$.......|
00000160  00 0d 0a 00 00 00 00 00  02 00 00 00 18 00 00 00  |................|
00000170  60 02 00 00 03 00 00 00  90 02 00 00 10 00 00 00  |`...............|
00000180  0b 00 00 00 50 00 00 00  00 00 00 00 00 00 00 00  |....P...........|
00000190  00 00 00 00 01 00 00 00  01 00 00 00 02 00 00 00  |................|
000001a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001d0  55 48 89 e5 b0 00 e8 00  00 00 00 b0 00 e8 00 00  |UH..............|
000001e0  00 00 31 c0 5d c3 00 00  00 00 00 00 00 00 00 00  |..1.]...........|
000001f0  16 00 00 00 00 00 00 01  00 00 00 00 00 00 00 00  |................|
00000200  00 00 00 00 00 00 00 00  14 00 00 00 00 00 00 00  |................|
00000210  01 7a 52 00 01 78 10 01  10 0c 07 08 90 01 00 00  |.zR..x..........|
00000220  24 00 00 00 1c 00 00 00  a8 ff ff ff ff ff ff ff  |$...............|
00000230  16 00 00 00 00 00 00 00  00 41 0e 10 86 02 43 0d  |.........A....C.|
00000240  06 00 00 00 00 00 00 00  0e 00 00 00 02 00 00 2d  |...............-|
00000250  07 00 00 00 01 00 00 2d  00 00 00 00 01 00 00 06  |.......-........|
00000260  01 00 00 00 0f 01 00 00  00 00 00 00 00 00 00 00  |................|
00000270  0a 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000280  07 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000290  00 5f 6d 61 69 6e 00 5f  62 00 5f 61 00 00 00 00  |._main._b._a....|
000002a0

ふむふむなるほど(無能)

結局意味がわからないので特に何も書くことがない。 とりあえずcatで連結するような単純なものではないらしい。

感想

リンカは結構単純な置換をやっているだけに見えるが、 ruiさんが

Cプリプロセッサの実装はかなり手間がかかる。

qiita.com

と書かれていたり

コンパイラの入門書で作成対象外になっていたりなどで

本書では、この4つの段階のうちプリプロセスを除いた、コンパイルアセンブル・リンクについてお話しします(普通のコンパイラを作ろうp8より)

作るとなると意外と難しいものなのかもしれない。