printfをたどる小さなメモ

# 前提
- Ubuntu 16.04
- VM Ware
- x86

# コード例

```c:test2.c
#include <stdio.h>

int main(int arg, char *argv[]){
        printf("hello\n");
}
```


# メモ

- #includeはCの文法ではなく、プリプロセッサの命令
    - stdio.hには標準関数の定義がたくさんある
    - #include は stdio.hの中身を展開しているだけ
- ヘッダファイルには大きく2通りある
    - システムに標準でインストールされているもの
        - #include <>
        - 標準ヘッダファイルは/usr/include というディレクトリに置かれている
        - stdio.hを見てみると、「the GNU C Library」と書かれており、glibcにコードがある（と思われる）
        - glibcのソースから `stdio.h` を検索すると3つ引っかかる
        - /usr/include の中にはglibc以外から提供されているものもある（Linuxカーネルやその他のライブラリ等）
        - 大体以下らしい
            - /usr/include/*.h: 標準Cライブラリ
            - /usr/include/sys/*.h: OSカーネル提供
            - /usr/include/net/*.h: ネットワーク関連
        - glibcの実体のありかは→らしい（Ubuntu 16.04） `/usr/lib/x86_64-linux-gnu/`
        - readelfで確認するとprintf.oがある
        - printf.cを探すと、glibcソース配下のstdio-commonディレクトリ配下にそれっぽいのが色々ある
        - printf.cを覗くと `vfprintf` を呼んでいるのが分かる。（ここで一旦終わり）
    - プログラム中で定義するローカルのもの
        - #include ""
- ヘッダファイルの場所
    - glibcの中にstdio.hがある

# Linuxのコード等

```sh:command
ubuntu# ls /usr/include | grep stdio
stdio.h
stdio_ext.h
```

```/usr/include/stdio.h
/* Define ISO C stdio on top of C++ iostreams.
   Copyright (C) 1991-2016 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */
```

```sh:command
ubuntu# find . -name "stdio.h"
./include/stdio.h
./libio/stdio.h
./libio/bits/stdio.h
```

```sh:commmand
ubuntu# readelf -a /usr/lib/x86_64-linux-gnu/libc.a | grep printf | grep -v "[a-z_]printf"
     9: 0000000000000480  9125 FUNC    LOCAL  DEFAULT    1 printf_positional
ファイル: libc.a(printf_fp.o)
ファイル: libc.a(reg-printf.o)
ファイル: libc.a(printf-prs.o)
ファイル: libc.a(printf_fphex.o)
ファイル: libc.a(printf_size.o)
    28: 0000000000000000  2223 FUNC    GLOBAL DEFAULT    1 printf_size
    29: 00000000000008b0    31 FUNC    GLOBAL DEFAULT    1 printf_size_info
ファイル: libc.a(printf.o)
    11: 0000000000000000   158 FUNC    GLOBAL DEFAULT    1 printf
    10: 0000000000000370 10733 FUNC    LOCAL  DEFAULT    1 printf_positional
ファイル: libc.a(printf-parsemb.o)
ファイル: libc.a(printf-parsewc.o)
ファイル: libc.a(printf_chk.o)
```

```sh:command
# find . -name "*printf.c" | grep comm
./stdio-common/fprintf.c
./stdio-common/asprintf.c
./stdio-common/printf.c
./stdio-common/reg-printf.c
./stdio-common/tst-obprintf.c
./stdio-common/tst-swprintf.c
./stdio-common/tst-wc-printf.c
./stdio-common/fxprintf.c
./stdio-common/vprintf.c
./stdio-common/vfwprintf.c
./stdio-common/dprintf.c
./stdio-common/vfprintf.c
./stdio-common/test-vfprintf.c
./stdio-common/sprintf.c
./stdio-common/tst-printf.c
./stdio-common/tst-sprintf.c
./stdio-common/snprintf.c
```

```c:stdio-common/printf.c(抜粋)
/* Write formatted output to stdout from the format string FORMAT.  */
/* VARARGS1 */
int
__printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}
```

# 参考

<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00O8GILDK/kuredev-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51IGe9CCYOL._SL160_.jpg" alt="本当は怖いC言語" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00O8GILDK/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">本当は怖いC言語</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 17.09.10</div></div><div class="amazlet-detail">秀和システム (2014-10-07)<br />売り上げランキング: 101,714<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00O8GILDK/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>

　
<div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798044784/kuredev-22/ref=nosim/" name="amazletlink" target="_blank"><img src="https://images-fe.ssl-images-amazon.com/images/I/51QDTm%2B6kdL._SL160_.jpg" alt="ハロー“Hello,World"OSと標準ライブラリのシゴトとしくみ" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10px"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798044784/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">ハロー“Hello,World"OSと標準ライブラリのシゴトとしくみ</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/" title="amazlet" target="_blank">amazlet</a> at 17.09.10</div></div><div class="amazlet-detail">坂井 弘亮 <br />秀和システム <br />売り上げランキング: 48,784<br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798044784/kuredev-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jpで詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>

glibcのインストールされているディレクトリとファイル名 | hydroculのメモ https://hydrocul.github.io/wiki/blog/2016/0220-glibc-filename.html