2014-04-10 78 views
1

假設您想要訪問數組中的結構,並修改幾個字段。你可以這樣做的直接,如:引用和數組索引之間的任何區別?

units[unitIndex].field1 = value1; 
units[unitIndex].field2 = value2; 
units[unitIndex].field3 = value3; 
... 

或者,你可以拉至結構的引用,然後從那裏修改它們:

unitStruct& unit = units[unitIndex]; 
unit.field1 = value1; 
unit.field2 = value2; 
unit.field3 = value3; 
... 

我一直認爲第二種方法是「更好「,它不必每次都重新索引到數組中以重新查找結構。

但是當我停下來思考它時,我意識到編譯器很可能將數組索引實現爲指針。而且這個參考也可能作爲一個指針來實現。也許他們在內部也在做同樣的事情?

所以我想知道的是,從編譯器的角度來看,生成的代碼,這兩種方法之間有什麼真正的區別?編譯器是否爲這些方法之一生成任何額外的代碼,或者它們本質上是獲得完全相同結果的兩種方法?

回答

2

當啓用優化編譯時,編譯器會以任何方式生成相同的代碼,您應該使用任何樣式使代碼對您和維護代碼的人更易讀。

例如

#include <cstddef> 
#include <vector> 

struct unitStruct { 
    int field1; 
    int field2; 
    int field3; 
}; 

void noref(std::vector<unitStruct> & units, size_t unitIndex, int value1, int value2, int value3) 
{ 
    units[unitIndex].field1 = value1; 
    units[unitIndex].field2 = value2; 
    units[unitIndex].field3 = value3; 
} 

void ref(std::vector<unitStruct> & units, size_t unitIndex, int value1, int value2, int value3) 
{ 
    unitStruct& unit = units[unitIndex]; 
    unit.field1 = value1; 
    unit.field2 = value2; 
    unit.field3 = value3; 
} 

用gcc編譯和優化啓用-O3

g++ -O3 -c struct.cpp -o struct.o 
objdump -D struct.o|less 

生成相同的代碼 - 前三個指令出現在不同的順序,但僅此而已:

0000000000000000 <_Z5norefRSt6vectorI10unitStructSaIS0_EEmiii>: 
    0: 48 8d 04 76    lea (%rsi,%rsi,2),%rax 
    4: 48 8b 37    mov (%rdi),%rsi 
    7: 48 8d 04 86    lea (%rsi,%rax,4),%rax 
    b: 89 10     mov %edx,(%rax) 
    d: 89 48 04    mov %ecx,0x4(%rax) 
    10: 44 89 40 08    mov %r8d,0x8(%rax) 
    14: c3      retq 

0000000000000020 <_Z3refRSt6vectorI10unitStructSaIS0_EEmiii>: 
    20: 4c 8b 0f    mov (%rdi),%r9 
    23: 48 8d 04 76    lea (%rsi,%rsi,2),%rax 
    27: 49 8d 04 81    lea (%r9,%rax,4),%rax 
    2b: 89 10     mov %edx,(%rax) 
    2d: 89 48 04    mov %ecx,0x4(%rax) 
    30: 44 89 40 08    mov %r8d,0x8(%rax) 
    34: c3      retq 
+0

您應該注意在-O3中啓用了優化。 –

+0

@RobK好點,我會強調這一點,謝謝。 – amdn

0

我幾乎不相信有什麼區別。 units[unitIndex]會給你一個unitStruct &。

我認爲唯一的區別是有人閱讀代碼。

1

在調試模式下,編譯器可以生成不同的代碼。對於單位[unitIndex],它可以計算每行的單位+單位索引指針。如果您使用參考,偏移量將被計算一次,並存儲在堆棧中。

在經過優化的版本中,在這兩種情況下,編譯器可能會執行一次計算並將計算出的偏移量保存在寄存器中。

重要的是,它更可讀,更易於維護。當你爲一件事情進行優化時,你會爲其他事情感到悲觀。在幾乎所有情況下,您都應該優化可讀性和可維護性。

[ETA]如果您真的對差異感到好奇,可以讓編譯器將生成的程序集寫入文件。有關如何執行此操作,請參閱編譯器的幫助。

相關問題