Wie kann man quellcodemaßig(rolf) checken ob eine Methode tatsächlich inlinde wurde?
-
Hallo zusammen,
es gibt mehrere Rumors darüber ob und wie die verschiedene c/c++ Kompiler die Methode freiwillig zum Inline machen bzw. auf eine die inline Anweisung verzichten
Kenn vllt jemand ein kurzer quellcode- trick um beim Laufzeit zu testen ob eine Methode inlined wurde oder per Pointer zu Speicherbereich aufgerufen wurde?Danke für Antworten.
-
Muss es ausgerechnet zur Laufzeit sein?
-
Gewünscht, aber nicht zwingend: ich würde mich auch auf Compilezeit oder Macros- checks interessieren.
-
o4kareg schrieb:
Gewünscht, aber nicht zwingend: ich würde mich auch auf Compilezeit oder Macros- checks interessieren.
Dann musst du in deinem Compilerhandbuch gucken. Manche Compiler (z.B. der von Intel) bieten die Option, ausführlich über gemachte Optimierungen zu berichten.
Eine allgemeine Methode wäre, sich nach dem Compilieren die erzeugte Datei anzusehen. Oft kann man sich auch direkt vom Compiler das Assembly ausgeben lassen (wieder: Compilerhandbuch). Oftmals lesbarer ist jedoch ein Disassembler (zumindest wenn du Debugsymbole eincompiliert hast). Z.B. unter Linux, mit GCC und objdump:
test.c:#include <stdio.h> int add(int a, int b) { return a + b; } int main() { int a,b; scanf("%i %i", &a, &b); printf("%i\n", add(a,b)); }
[b]$> [/b]gcc -g -O0 test.c [b]$> [/b]objdump --demangle --line-numbers --debugging --disassemble-all --source --all-header ./a.out #Hier nur relevanter Teil der Ausgabe gezeigt: int main() { 400550: 55 push %rbp 400551: 48 89 e5 mov %rsp,%rbp 400554: 48 83 ec 10 sub $0x10,%rsp /home/zensiert/src/test/test.c:11 int a,b; scanf("%i %i", &a, &b); 400558: 48 8d 55 f8 lea -0x8(%rbp),%rdx 40055c: 48 8d 45 fc lea -0x4(%rbp),%rax 400560: 48 89 c6 mov %rax,%rsi 400563: bf 4c 06 40 00 mov $0x40064c,%edi 400568: b8 00 00 00 00 mov $0x0,%eax 40056d: e8 ae fe ff ff callq 400420 <__isoc99_scanf@plt> /home/zensiert/src/test/test.c:12 printf("%i\n", add(a,b)); 400572: 8b 55 f8 mov -0x8(%rbp),%edx 400575: 8b 45 fc mov -0x4(%rbp),%eax 400578: 89 d6 mov %edx,%esi 40057a: 89 c7 mov %eax,%edi 40057c: e8 bb ff ff ff callq 40053c <add> 400581: 89 c6 mov %eax,%esi 400583: bf 52 06 40 00 mov $0x400652,%edi 400588: b8 00 00 00 00 mov $0x0,%eax 40058d: e8 6e fe ff ff callq 400400 <printf@plt> /home/zensiert/src/test/test.c:13 }
[b]$> [/b]gcc -g -O3 test.c [b]$> [/b]objdump --demangle --line-numbers --debugging --disassemble-all --source --all-header ./a.out #Hier nur relevanter Teil der Ausgabe gezeigt: int main() { 400430: 48 83 ec 18 sub $0x18,%rsp /home/zensiert/src/test/test.c:11 int a,b; scanf("%i %i", &a, &b); 400434: bf 2c 06 40 00 mov $0x40062c,%edi 400439: 31 c0 xor %eax,%eax 40043b: 48 8d 54 24 0c lea 0xc(%rsp),%rdx 400440: 48 8d 74 24 08 lea 0x8(%rsp),%rsi 400445: e8 d6 ff ff ff callq 400420 <__isoc99_scanf@plt> add(): /home/zensiert/src/test/test.c:5 #include <stdio.h> int add(int a, int b) { return a + b; 40044a: 8b 74 24 0c mov 0xc(%rsp),%esi 40044e: 03 74 24 08 add 0x8(%rsp),%esi main(): /home/zensiert/src/test/test.c:12 int main() { int a,b; scanf("%i %i", &a, &b); printf("%i\n", add(a,b)); 400452: bf 32 06 40 00 mov $0x400632,%edi 400457: 31 c0 xor %eax,%eax 400459: e8 a2 ff ff ff callq 400400 <printf@plt> /home/zensiert/src/test/test.c:13 }
Man sieht selbst ohne tiefergehende Assemblerkenntnisse, dass die funktion bei der unoptimierten Variante explizit aufgerufen wird, während sie bei der zweiten Variante in den Code der main-Funktion eingebaut wurde.
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
MSVC hat __forceinline, da kommt dann laut MSDN ne Level 1 Warning wenn die Funktion nicht geinlined werden konnte.
Wobei der Compiler bei __forceinline dann auf Teufel komm raus versucht die Funktion inline zu machen, was also überhaupt nicht dem verhalten ohne __forceinline entspricht.