[Update] 2016.07.02eine Standardfunktion Aufschalten verhält sich unerwartet
main.c
#include <stdio.h>
#include <string.h>
size_t strlen(const char *str) {
printf("%s\n", str);
return 99;
}
int main() {
const char *str = "AAA";
size_t a = strlen(str);
strlen(str);
size_t b = strlen("BBB");
return 0;
}
die erwartete Ausgabe ist
AAA
AAA
BBB
Compilieren mit gcc -O0 -o Haupt main. c:
AAA
Kompilieren mit gcc h -O3 -o Haupt main.c
AAA
AAA
Der entsprechende Code mit ASM-Flag -O0
000000000040057c <main>:
40057c: 55 push %rbp
40057d: 48 89 e5 mov %rsp,%rbp
400580: 48 83 ec 20 sub $0x20,%rsp
400584: 48 c7 45 e8 34 06 40 movq $0x400634,-0x18(%rbp)
40058b: 00
40058c: 48 8b 45 e8 mov -0x18(%rbp),%rax
400590: 48 89 c7 mov %rax,%rdi
400593: e8 c5 ff ff ff callq 40055d <strlen>
400598: 48 89 45 f0 mov %rax,-0x10(%rbp)
40059c: 48 c7 45 f8 03 00 00 movq $0x3,-0x8(%rbp)
4005a3: 00
4005a4: b8 00 00 00 00 mov $0x0,%eax
4005a9: c9 leaveq
4005aa: c3 retq
4005ab: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
und mit -O3:
0000000000400470 <main>:
400470: 48 83 ec 08 sub $0x8,%rsp
400474: bf 24 06 40 00 mov $0x400624,%edi
400479: e8 c2 ff ff ff callq 400440 <[email protected]>
40047e: bf 24 06 40 00 mov $0x400624,%edi
400483: e8 b8 ff ff ff callq 400440 <[email protected]>
400488: 31 c0 xor %eax,%eax
40048a: 48 83 c4 08 add $0x8,%rsp
40048e: c3 retq
mit der Flagge -O0, Warum ruft der zweite und dritte Aufruf von strlen nicht den benutzerdefinierten strlen an?
Und mit -O3, warum ist der dritte Aufruf zu Strlen optimiert worden?
Wahrscheinlich, weil der Compiler die redundanten Aufrufe optimiert hat, aber das ist ein bisschen seltsam, wenn man bedenkt, dass es Nebenwirkungen in Ihrer Implementierung hat. Nicht sicher, wie weit es mit bekannten Funktionen wie 'strlen()' gehen wird. Einzelschritt den Code in einem Debugger. – unwind
Angenommen, dies ist gcc, versuchen Sie, es mit '-fno-optimize-strlen' zu kompilieren. – tofro
Ändern Sie den Namen der Funktion in' my_strlen' und sehen Sie, was passiert. Und entfernen Sie 'extern' Schlüsselwort in der Funktionsimplementierung. – LPs