2010-06-25 78 views
2

假設我們有一些功能使用深度嵌套的指針非常廣泛:使用深度嵌套的指針

function (ptr_a_t ptr_a) { 
    ... 
    a = ptr_a->ptr_b->ptr_c->val; 
    b = ptr_a->ptr_b->ptr_c->val; 
    ... 
} 

假定所有的指針進行檢查和有效的,有沒有性能下降,與原子或其他注意事項的問題(除可讀性)與比較:

function (ptr_a_t ptr_a) { 
    val = ptr_a->ptr_b->ptr_c->val; 
    ... 
    a = val; 
    b = val; 
    ... 
} 

更新 我編譯這個C文件(僅用於研究目的而編寫)用gcc -S:

typedef struct { 
    int val; 
} c_str_t; 

typedef struct { 
    c_str_t *p_c;  
} b_str_t; 

typedef struct { 
    b_str_t *p_b;  
} a_str_t; 

void func (a_str_t *p_a) 
{ 
    int a,b; 

    a = p_a->p_b->p_c->val; 
    b = p_a->p_b->p_c->val; 

    printf("", a,b); 
} 

對於GCC -S:

movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, -4(%ebp) 
movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, -8(%ebp) 

對於GCC -S -O1:

movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, 8(%esp) 
movl %eax, 4(%esp) 

相同我觀察使用內部結構揮發性 specificator。 因此,嵌套指針被強制優化。

+0

另一種選擇:a = b = ptr_a-> ptr_b-> ptr_c-> val; – Nyan 2010-06-26 03:30:40

回答

2

這些是否會被視爲相同取決於實現。以兩種方式編譯代碼並檢查程序集輸出以查看編譯器如何處理這兩種情況。

在我正在開發的嵌入式系統上,我添加了一個「中間」指針,就像你做的那樣,並且在函數的執行時間中看到了明顯的加速。就我而言,編譯器每次都從頭開始重新計算指針鏈,而不是優化它們。你的編譯器可能不同,唯一真正的方法是雙向嘗試並測量執行時間。

+0

你是對的。沒有優化,gcc會重新計算指針。查看我的更新。 – pmod 2010-06-27 17:43:05

2

我敢肯定,你的編譯器會優化兩個相同的代碼作爲gcc。

您可以通過爲兩者(在gcc中使用-S開關)生成彙編代碼並比較它們來非常容易地檢查它。

3

除非其中一些中間結構成員標記爲易失性,編譯器應該將您的兩個示例視爲等同。我更喜歡你的第二個代碼示例,只是因爲它看起來更乾淨。

+1

請注意,它表示*應*將它們視爲等同物。沒有規定說這必須或不可能發生,它依賴於特定的編譯器(可能還有所使用的優化選項)。 – bta 2010-06-25 21:11:43

+0

現在,在第一種情況下,優化器現在是否可以在兩行之間不更改其中一個指針(由於調度程序)? – pmod 2010-06-25 21:19:05

+2

@Pmod:除非標記爲「volatile」,否則編譯器可以假定變量在函數中間不會自發地改變。 – Karmastan 2010-06-25 21:20:29