C語言中restrict關鍵字學習

來源:互聯網
上載者:User

簡介:

restrict是c99標準引入的,它只可以用於限定和約束指標,並表明指標是訪問一個資料對象的唯一且初始的方式.即它告訴編譯器,所有修改該指標所指向記憶體中內容的操作都必須通過該指標來修改,而不能通過其它途徑(其它變數或指標)來修改;這樣做的好處是,能協助編譯器進行更好的最佳化代碼,產生更有效率的彙編代碼.如 int *restrict ptr, ptr 指向的記憶體單元只能被 ptr 訪問到,任何同樣指向這個記憶體單元的其他指標都是未定義的,直白點就是無效指標。restrict 的出現是因為 C 語言本身固有的缺陷,C 程式員應當主動地規避這個缺陷,而編譯器也會很配合地最佳化你的代碼.

考慮下面的例子:
  int ar[10];
  int * restrict restar=(int *)malloc(10*sizeof(int));
  int *par=ar;
  這裡說明restar是訪問由malloc()分配的記憶體的唯一且初始的方式。par就不是了。
  那麼:
  for(n=0;n<10;n++)
  {
  par[n]+=5;
  restar[n]+=5;
  ar[n]*=2;
  par[n]+=3;
  restar[n]+=3;
  }
  因為restar是訪問分配的記憶體的唯一且初始的方式,那麼編譯器可以將上述對restar的操作進行最佳化:
  restar[n]+=8;
  而par並不是訪問數組ar的唯一方式,因此並不能進行下面的最佳化:
  par[n]+=8;
  因為在par[n]+=3前,ar[n]*=2進行了改變。使用了關鍵字restrict,編譯器就可以放心地進行最佳化了。
  這個關鍵字據說來源於古老的FORTRAN。有興趣的看看這個。

C庫中有兩個函數可以從一個位置把位元組複製到另一個位置。在C99標準下,它們的原型如下:
  void * memcpy(void * restrict s1, const void * restrict s2, size_t n);
  void * memove(void * s1, const void * s2, size_t n);
  這兩個函數均從s2指向的位置複製n位元組資料到s1指向的位置,且均返回s1的值。兩者之間的差別由關鍵字restrict造成,即memcpy()可以假定兩個記憶體地區沒有重疊。memmove()函數則不做這個假定,因此,複製過程類似於首先將所有位元組複製到一個臨時緩衝區,然後再複製到最終目的地。如果兩個地區存在重疊時使用memcpy()會怎樣。其行為是不可預知的,既可以正常工作,也可能失敗。在不應該使用memcpy()時,編譯器不會禁止使用memcpy()。因此,使用memcpy()時,您必須確保沒有重疊地區。這是程式員的任務的一部分。
  關鍵字restrict有兩個讀者。一個是編譯器,它告訴編譯器可以自由地做一些有關最佳化的假定。另一個讀者是使用者,他告訴使用者僅使用滿足restrict要求的參數。一般,編譯器無法檢查您是否遵循了這一限制,如果您蔑視它也就是在讓自己冒險。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.