GCC 关键字inline探究
生活随笔
收集整理的這篇文章主要介紹了
GCC 关键字inline探究
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、inline介紹
先看造型:
inline int test() { ? ? ...... ? ? return 0; }
int main() { ? ? test(); ? ? return 0; }
我們知道,如果test函數沒有inline關鍵字修飾的時候,程序執行到調用test的時候,會從main函數跳到test函數執行。為了從test函數返回到mian函數后,能從調用test函數的下一條指令執行,在調用test函數前,我們必須對現場進行保護(將一些寄存器的值壓棧)。
那如果加了inline關鍵字呢,那編譯系統就會將test函數當做一個宏來處理,即直接在main函數中展開。在這里需要注意的是,并不是所有函數加上inline關鍵字就一定會在main函數中展開,一般要求inline關鍵字盡可能的簡單。
二、反匯編看效果
源碼:
#include <stdio.h>
static inline int test1() { int a = 1;
printf("Hello test1.\n");
return a; }
static inline int test2() { int b = 2;
printf("Hello test2.\n");
return b; }
int main() { test1(); test2();
return 0; }
第一次編譯: arm-none-linux-gnueabi-gcc inline.c -o inline
反匯編如下: arm-none-linux-gnueabi-objdump -d inline > log
查看log文件 cat log:
部分匯編代碼 000083d4 <main>: ? ? 83d4: e1a0c00d? mov ip, sp ? ? 83d8: e92dd800? push {fp, ip, lr, pc} ? ? 83dc: e24cb004? sub fp, ip, #4 ; 0x4 ? ??83e0: eb000005? bl 83fc <test1> ? ? 83e4: eb000012? bl 8434 <test2> ? ? 83e8: e3a03000? mov r3, #0 ; 0x0 ? ? 83ec: e1a00003? mov r0, r3 ? ? 83f0: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 83f4: e89d6800? ldm sp, {fp, sp, lr} ? ? 83f8: e12fff1e? bx lr
000083fc <test1>: ? ? 83fc: e1a0c00d? mov ip, sp ? ? 8400: e92dd800? push {fp, ip, lr, pc} ? ? 8404: e24cb004? sub fp, ip, #4 ; 0x4 ? ? 8408: e24dd008? sub sp, sp, #8 ; 0x8 ? ? 840c: e3a03001? mov r3, #1 ; 0x1 ? ? 8410: e50b3010? str r3, [fp, #-16] ? ? 8414: e59f0014? ldr r0, [pc, #20] ; 8430 <test1+0x34> ? ? 8418: ebffffb9? bl 8304 <_init+0x50> ? ? 841c: e51b3010? ldr r3, [fp, #-16] ? ? 8420: e1a00003? mov r0, r3 ? ? 8424: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 8428: e89d6800? ldm sp, {fp, sp, lr} ? ? 842c: e12fff1e? bx lr ? ? 8430: 00008504? .word 0x00008504
00008434 <test2>: ? ? 8434: e1a0c00d? mov ip, sp ? ? 8438: e92dd800? push {fp, ip, lr, pc} ? ? 843c: e24cb004? sub fp, ip, #4 ; 0x4 ? ? 8440: e24dd008? sub sp, sp, #8 ; 0x8 ? ? 8444: e3a03002? mov r3, #2 ; 0x2 ? ? 8448: e50b3010? str r3, [fp, #-16] ? ? 844c: e59f0014? ldr r0, [pc, #20] ; 8468 <test2+0x34> ? ? 8450: ebffffab? bl 8304 <_init+0x50> ? ? 8454: e51b3010? ldr r3, [fp, #-16] ? ? 8458: e1a00003? mov r0, r3 ? ? 845c: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 8460: e89d6800? ldm sp, {fp, sp, lr} ? ? 8464: e12fff1e? bx lr ? ? 8468: 00008514? .word 0x00008514
第二次編譯
arm-none-linux-gnueabi-gcc -O ?inline.c -o inline
反匯編如下: arm-none-linux-gnueabi-objdump -d inline > log
查看log文件 cat log:
000083d4 <main>: ? ? 83d4: e52de004? push {lr} ; (str lr, [sp, #-4]!) ? ? 83d8: e24dd004? sub sp, sp, #4 ; 0x4 ? ? 83dc: e59f0018? ldr r0, [pc, #24] ; 83fc <main+0x28> ? ? 83e0: ebffffc7? bl 8304 <_init+0x50> ? ? 83e4: e59f0014? ldr r0, [pc, #20] ; 8400 <main+0x2c> ? ? 83e8: ebffffc5? bl 8304 <_init+0x50> ? ? 83ec: e3a00000? mov r0, #0 ; 0x0 ? ? 83f0: e28dd004? add sp, sp, #4 ; 0x4 ? ? 83f4: e49de004? pop {lr} ; (ldr lr, [sp], #4) ? ? 83f8: e12fff1e? bx lr ? ? 83fc: 0000849c? .word 0x0000849c ? ? 8400: 000084ac? .word 0x000084ac
總結如下: 對于inine關鍵字,如果在編譯的時候不加優化選項(-O 或 -O2)時,編譯系統不會將其修飾的函數在mian函數中展開。但是會把被inline修飾的函數 代碼按其在main函數中的調用順序放在main后面。 如果在編譯的時候加了優化選項,被inline修飾的函數大部分情況下會在main函數中展開。
注意:inline是一個建議型關鍵字,具體有沒有被展開反匯編一看便知。
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html
先看造型:
inline int test() { ? ? ...... ? ? return 0; }
int main() { ? ? test(); ? ? return 0; }
我們知道,如果test函數沒有inline關鍵字修飾的時候,程序執行到調用test的時候,會從main函數跳到test函數執行。為了從test函數返回到mian函數后,能從調用test函數的下一條指令執行,在調用test函數前,我們必須對現場進行保護(將一些寄存器的值壓棧)。
那如果加了inline關鍵字呢,那編譯系統就會將test函數當做一個宏來處理,即直接在main函數中展開。在這里需要注意的是,并不是所有函數加上inline關鍵字就一定會在main函數中展開,一般要求inline關鍵字盡可能的簡單。
二、反匯編看效果
源碼:
#include <stdio.h>
static inline int test1() { int a = 1;
printf("Hello test1.\n");
return a; }
static inline int test2() { int b = 2;
printf("Hello test2.\n");
return b; }
int main() { test1(); test2();
return 0; }
第一次編譯: arm-none-linux-gnueabi-gcc inline.c -o inline
反匯編如下: arm-none-linux-gnueabi-objdump -d inline > log
查看log文件 cat log:
部分匯編代碼 000083d4 <main>: ? ? 83d4: e1a0c00d? mov ip, sp ? ? 83d8: e92dd800? push {fp, ip, lr, pc} ? ? 83dc: e24cb004? sub fp, ip, #4 ; 0x4 ? ??83e0: eb000005? bl 83fc <test1> ? ? 83e4: eb000012? bl 8434 <test2> ? ? 83e8: e3a03000? mov r3, #0 ; 0x0 ? ? 83ec: e1a00003? mov r0, r3 ? ? 83f0: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 83f4: e89d6800? ldm sp, {fp, sp, lr} ? ? 83f8: e12fff1e? bx lr
000083fc <test1>: ? ? 83fc: e1a0c00d? mov ip, sp ? ? 8400: e92dd800? push {fp, ip, lr, pc} ? ? 8404: e24cb004? sub fp, ip, #4 ; 0x4 ? ? 8408: e24dd008? sub sp, sp, #8 ; 0x8 ? ? 840c: e3a03001? mov r3, #1 ; 0x1 ? ? 8410: e50b3010? str r3, [fp, #-16] ? ? 8414: e59f0014? ldr r0, [pc, #20] ; 8430 <test1+0x34> ? ? 8418: ebffffb9? bl 8304 <_init+0x50> ? ? 841c: e51b3010? ldr r3, [fp, #-16] ? ? 8420: e1a00003? mov r0, r3 ? ? 8424: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 8428: e89d6800? ldm sp, {fp, sp, lr} ? ? 842c: e12fff1e? bx lr ? ? 8430: 00008504? .word 0x00008504
00008434 <test2>: ? ? 8434: e1a0c00d? mov ip, sp ? ? 8438: e92dd800? push {fp, ip, lr, pc} ? ? 843c: e24cb004? sub fp, ip, #4 ; 0x4 ? ? 8440: e24dd008? sub sp, sp, #8 ; 0x8 ? ? 8444: e3a03002? mov r3, #2 ; 0x2 ? ? 8448: e50b3010? str r3, [fp, #-16] ? ? 844c: e59f0014? ldr r0, [pc, #20] ; 8468 <test2+0x34> ? ? 8450: ebffffab? bl 8304 <_init+0x50> ? ? 8454: e51b3010? ldr r3, [fp, #-16] ? ? 8458: e1a00003? mov r0, r3 ? ? 845c: e24bd00c? sub sp, fp, #12 ; 0xc ? ? 8460: e89d6800? ldm sp, {fp, sp, lr} ? ? 8464: e12fff1e? bx lr ? ? 8468: 00008514? .word 0x00008514
第二次編譯
arm-none-linux-gnueabi-gcc -O ?inline.c -o inline
反匯編如下: arm-none-linux-gnueabi-objdump -d inline > log
查看log文件 cat log:
000083d4 <main>: ? ? 83d4: e52de004? push {lr} ; (str lr, [sp, #-4]!) ? ? 83d8: e24dd004? sub sp, sp, #4 ; 0x4 ? ? 83dc: e59f0018? ldr r0, [pc, #24] ; 83fc <main+0x28> ? ? 83e0: ebffffc7? bl 8304 <_init+0x50> ? ? 83e4: e59f0014? ldr r0, [pc, #20] ; 8400 <main+0x2c> ? ? 83e8: ebffffc5? bl 8304 <_init+0x50> ? ? 83ec: e3a00000? mov r0, #0 ; 0x0 ? ? 83f0: e28dd004? add sp, sp, #4 ; 0x4 ? ? 83f4: e49de004? pop {lr} ; (ldr lr, [sp], #4) ? ? 83f8: e12fff1e? bx lr ? ? 83fc: 0000849c? .word 0x0000849c ? ? 8400: 000084ac? .word 0x000084ac
總結如下: 對于inine關鍵字,如果在編譯的時候不加優化選項(-O 或 -O2)時,編譯系統不會將其修飾的函數在mian函數中展開。但是會把被inline修飾的函數 代碼按其在main函數中的調用順序放在main后面。 如果在編譯的時候加了優化選項,被inline修飾的函數大部分情況下會在main函數中展開。
注意:inline是一個建議型關鍵字,具體有沒有被展開反匯編一看便知。
原文地址: http://blog.chinaunix.net/uid-26833883-id-3351281.html
總結
以上是生活随笔為你收集整理的GCC 关键字inline探究的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 标准IO缓冲机制探究
- 下一篇: JNI实战