2011-09-07 42 views
8

我有收到像這樣的指針數組功能:如何判斷一個C或指針沒有別名C++編譯器

void foo(int *ptrs[], int num, int size) 
{ 
    /* The body is an example only */ 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < num-1; ++j) 
     ptrs[num-1][i] += ptrs[j][i]; 
    } 
} 

我想傳達給編譯器的指針ptrs[i]是不是彼此的別名,並且陣列ptrs[i]不重疊。我該怎麼做?我的另一個動機是鼓勵自動矢量化。

另外,有沒有辦法在std::vector的迭代器上獲得與__restrict__相同的效果?

+1

重要提示:C++標準不支持從C99的'restrict'預選賽 - 它不是甚至一個關鍵字。因此,在C++程序中使用'restrict'是依賴於實現擴展 –

回答

9

restrict,不同於更常見const,是指針的性質而非數據指向。因此它屬於'*'聲明符修飾符的右側側。 []中的參數聲明是另一種寫法*。把這些東西放在一起,你應該能夠得到這個函數原型你想要的效果:

void foo(int *restrict *restrict ptrs, int num, int size) 
{ 
    /* body */ 
} 

,且無需新的名稱。 (未測試您的里程可能會有所不同restrict是一個純粹的優化暗示,實際上可能沒有做任何建設性你的編譯器。)

+2

除非我誤解了,那些「限制」聲明之一是多餘的;沒有其他「int **」類型的變量可能會出現鋸齒。 「int * restrict * ptrs」應該完成這項工作。我不知道是否「int * restrict ptrs []」可能也會這樣做...... – davmac

+0

恕我直言,兩個'restrict's都是必需的,因爲其他指針可能存在於'foo'範圍之外。 –

+0

「我想傳達給編譯器的是指針......不是*彼此的別名*「 – davmac

4

在C++中,如果指針指向基本不同的類型(「嚴格別名」規則),則指針參數不會被別名。

在C99中,「restrict」關鍵字指定指針參數不會別名任何其他指針參數。

+1

很確定嚴格的別名規則適用於'c'和'C++'。 http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

+0

@Darren謝謝,很好學習。 –

+1

是的,是的。此外,這個答案不會告訴OP他或她不知道的任何內容。 – zwol

7

喜歡的東西:

void foo(int *ptrs[], int num, int size) 
{ 
    /* The body is an example only */ 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < num-1; ++j) { 
     int * restrict a = ptrs[num-1]; 
     int * restrict b = ptrs[j]; 
     a[i] += b[i]; 
    } 
} 

...應該這樣做,我認爲,在C99。我不認爲在C++中有任何方法,但許多C++編譯器也支持限制。

+0

啊我看到了,我不得不介紹新的名字。謝謝。 – san

+1

順便提一句,您可以使用類似的技巧將迭代器標記對象引用爲非混淆(即將其地址分配給受限制的指針)。 – davmac

+1

你在''''''的錯誤一側有''restrict''限定符。 – zwol