私はstrlen.c
に、次のしている場合:その後、ClangのBuiltinsは組み込まれていないのですか?
int call_strlen(char *s) {
return __builtin_strlen(s);
}
そして、このようにgccと打ち鳴らすの両方でそれをコンパイルします。
gcc -c -o strlen-gcc.o strlen.c
clang -c -o strlen-clang.o strlen.c
私はstrlen関数-clang.oは、基準が含まれていることを見て驚いています"strlen"に変更しますが、gccは期待して関数をインライン展開し、そのような参照はありません。 (以下のobjdumpsを参照してください)。これはclangのバグですか?私は3.8を含むclangコンパイラのいくつかのバージョンでそれをテストしました。
編集:これは私にとって重要な理由は、私が-nostdlib
とリンクしていることです。そしてclangコンパイルされたバージョンでは、strlenが見つからないというリンクエラーが発生します。
クラン
@> objdump -d strlen-clang.o
strlen-clang.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <call_strlen>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
c: 48 8b 7d f8 mov -0x8(%rbp),%rdi
10: e8 00 00 00 00 callq 15 <call_strlen+0x15>
15: 89 c1 mov %eax,%ecx
17: 89 c8 mov %ecx,%eax
19: 48 83 c4 10 add $0x10,%rsp
1d: 5d pop %rbp
1e: c3 retq
@> objdump -t strlen-clang.o
strlen-clang.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 strlen.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 g F .text 000000000000001f call_strlen
0000000000000000 *UND* 0000000000000000 strlen
GCC
@> objdump -d strlen-gcc.o
strlen-gcc.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <call_strlen>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 89 7d f8 mov %rdi,-0x8(%rbp)
8: 48 8b 45 f8 mov -0x8(%rbp),%rax
c: 48 c7 c1 ff ff ff ff mov $0xffffffffffffffff,%rcx
13: 48 89 c2 mov %rax,%rdx
16: b8 00 00 00 00 mov $0x0,%eax
1b: 48 89 d7 mov %rdx,%rdi
1e: f2 ae repnz scas %es:(%rdi),%al
20: 48 89 c8 mov %rcx,%rax
23: 48 f7 d0 not %rax
26: 48 83 e8 01 sub $0x1,%rax
2a: 5d pop %rbp
2b: c3 retq
@> objdump -t strlen-gcc.o
strlen-gcc.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 strlen.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000002c call_strlen
最適化するようにコンパイラを設定していないため、clangは最適化されませんでした。ショッキング。 – EOF
@EOFどのように関連性がありますか?確かに、組み込み関数を使用するように言われれば、組み込み関数を使うべきです - 「最適化モードで組み込み関数を使うのではなく、おそらくあなたが悩まされるかもしれません。 'builtin'は' inline'のようなオプションのリクエストですか?もしそうなら、それを指定するClangのドキュメントのビットに私たちをリンクさせることができますか? –
@EOF FYI私は '-O3'でコンパイルしましたが、アセンブリはかなり短く、' jmp _strlen'を含んでいます。 – Siguza