OGT 様、Yoshino 様

謎が解けました。ありがとうございました。

On Mon, Aug 17, 2020 at 1:00 AM YOSHINO Yoshihito <yy.y.ja.jp@gmail.com> wrote:
よしのです
-O0 でもコンパイル時に計算してるらしい

$ echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst
double d = sqrt(4.0);\nprintf(\"\%lf\\\\n\", d);}" | env
SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -c -o without_libm.o -xc
-
$ echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst
double d = 2.0;\nprintf(\"\%lf\\\\n\", d);}" | env
SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -c -o without_libm_2.o
-xc -
$ diff -qs without_libm.o without_libm_2.o
ファイル without_libm.o と without_libm_2.o は同一です
$

$ echo -e "#include<math.h>\n#include<stdlib.h>\n#include<stdio.h>\nint
main(int argc, char **argv){\nif (argc < 2) exit(1);\nconst double d =
sqrt(strtod(argv[1], NULL));\nprintf(\"\%lf\\\\n\", d);}" | env
SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -o without_libm -xc -
/usr/bin/ld: /tmp/ccPLXWsj.o: in function `main':
:(.text+0x38): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
$ echo -e "#include<math.h>\n#include<stdlib.h>\n#include<stdio.h>\nint
main(int argc, char **argv){\nif (argc < 2) exit(1);\nconst double d =
sqrt(strtod(argv[1], NULL));\nprintf(\"\%lf\\\\n\", d);}" | env
SOURCE_DATE_EPOCH=1597590000 gcc -W -Wall -O0 -o with_libm -xc - -lm
$ ./with_libm 4.0
2.000000
$ ./with_libm 9.0
3.000000
$

--
YOSHINO Yoshihito <yy.y.ja.jp@gmail.com>

On Sun, Aug 16, 2020 at 10:57 PM Yosuke Otsuki <y.otsuki30@gmail.com> wrote:
>
> Debian User と Debian 開発者の皆様
>
> お世話になっております。オオツキです。
> 自分で調査してみましたがわからなかったので、ご存知の方がいらっしゃれば教えていただきたいです。
>
> まず、以下の bash script を実行すると、私の環境ではスクリプトに続くようになりました。
> * run.sh
> #!/bin/bash
>
> dpkg -l | grep gcc
> dpkg -l | grep binutils
>
> echo "=================================="
> echo -e "#include<math.h>\n#include<stdio.h>\nint main(){\nconst double d = sqrt(4.0);\nprintf(\"\%lf\", d);}" > main.c
> gcc -o without_libm main.c
> ldd without_libm
> readelf -a without_libm | grep libm
> ./without_libm
> echo "-----------------------------------"
> gcc -o with_libm main.c -lm
> ldd with_libm
> readelf -a with_libm | grep libm
> ./without_libm
>
> * 実行結果
> + dpkg -l
> + grep gcc
> ii  gcc                                  4:8.3.0-1                           amd64        GNU C compiler
> ii  gcc-8                                8.3.0-6                             amd64        GNU C compiler
> ii  gcc-8-base:amd64                     8.3.0-6                             amd64        GCC, the GNU Compiler Collection (base package)
> ii  gccgo-8                              8.3.0-6                             amd64        GNU Go compiler
> ii  gccgo-go                             2:1.11~1                            amd64        Go programming language -- gccgo
> ii  libgcc-8-dev:amd64                   8.3.0-6                             amd64        GCC support library (development files)
> ii  libgcc1:amd64                        1:8.3.0-6                           amd64        GCC support library
> ii  linux-compiler-gcc-8-x86             4.19.118-2+deb10u1                  amd64        Compiler for Linux on x86 (meta-package)
> + dpkg -l
> + grep binutils
> ii  binutils                             2.31.1-16                           amd64        GNU assembler, linker and binary utilities
> ii  binutils-common:amd64                2.31.1-16                           amd64        Common files for the GNU assembler, linker and binary utilities
> ii  binutils-x86-64-linux-gnu            2.31.1-16                           amd64        GNU binary utilities, for x86-64-linux-gnu target
> ii  libbinutils:amd64                    2.31.1-16                           amd64        GNU binary utilities (private shared library)
> + echo ==================================
> ==================================
> + echo -e '#include<math.h>\n#include<stdio.h>\nint main(){\nconst double d = sqrt(4.0);\nprintf("\%lf", d);}'
> + gcc -o without_libm main.c
> + ldd without_libm
> linux-vdso.so.1 (0x00007ffc85995000)
> libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02236d9000)
> /lib64/ld-linux-x86-64.so.2 (0x00007f02238b7000)
> + grep libm
> + readelf -a without_libm
> + ./without_libm
> 2.000000+ echo -----------------------------------
> -----------------------------------
> + gcc -o with_libm main.c -lm
> + ldd with_libm
> linux-vdso.so.1 (0x00007ffec8def000)
> libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb5a8ff8000)
> libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb5a8e37000)
> /lib64/ld-linux-x86-64.so.2 (0x00007fb5a9198000)
> + grep libm
> + readelf -a with_libm
>  0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
> + ./without_libm
> 2.000000
>
> libm から数学関数の sqrt() を読んでいます。
>
> 以前は、libm を明示的にリンクしないと、リンク時にエラーだったと記憶しているのですが、使用した環境ではこのオプションが不要でした。
> おそらく、自動的に libm がリンクされているのだろうと考えて名前解決がどうなっているのか見てみたところ、オプションを与えない場合 dyanmic section に libm がありませんでした。
> libm のリンクを明示的にしない場合、どのようにして sqrt() が呼び出されているのでしょうか?
>
> よろしくおねがいします。
> _______________________________________________
> debian-devel mailing list
> debian-devel@debian.or.jp
> https://lists.debian.or.jp/mailman/listinfo/debian-devel