亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

const在C / C ++中提供什么樣的優化?

const在C / C ++中提供什么樣的優化?

C++ C
瀟瀟雨雨 2019-11-18 12:54:49
我知道,出于可讀性原因,在通過引用或指針傳遞參數時,應盡可能使用const關鍵字。如果我指定參數為常量,編譯器可以進行任何優化嗎?可能有幾種情況:功能參數:常數參考:void foo(const SomeClass& obj)常量SomeClass對象:void foo(const SomeClass* pObj)和指向SomeClass的常量指針:void foo(SomeClass* const pObj)變量聲明:const int i = 1234函數聲明:const char* foo()每個人提供什么樣的編譯器優化(如果有)?
查看完整描述

3 回答

?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

情況1:-


當您在程序中聲明const時,


int const x = 2;

編譯器可以通過不為該變量提供存儲,而是將其添加到符號表中來優化此const。因此,后續讀取僅需要間接進入符號表,而不是從內存中獲取值的指令。


注意:-如果您執行以下操作:-


const int x = 1;

const int* y = &x;

然后,這將迫使編譯器為分配空間'x'。因此,這種情況下的優化程度是不可能的。


就功能而言,參數const表示未在函數中修改參數。據我所知,使用const它并不會帶來實質性的性能提升,而是確保正確性的一種手段。


案例_2:-


“將參數和/或返回值聲明為const是否有助于編譯器生成更多優化代碼?”


  const Y& f( const X& x )

  {

    // ... do something with x and find a Y object ...

    return someY;

  }

Ques =>編譯器可以做得更好嗎?


=>是否可以避免復制參數或返回值?


否,因為參數已通過引用傳遞。


=>可以將x或someY的副本放入只讀內存嗎?


否,因為x和someY都超出其范圍,并且來自和/或提供給外部世界。即使someY在f()本身內部動態地動態分配,它和它的所有權也由調用者放棄。


Ques =>關于出現在f()主體內部的代碼的可能的優化呢?由于使用了const,編譯器能否以某種方式改進它為f()主體生成的代碼?


即使您調用const成員函數,編譯器也無法假定對象x或對象someY的位不會更改。此外,還有其他問題(除非編譯器執行全局優化):編譯器也可能不確定是否其他代碼可能沒有非常量引用來別名相同的對象作為x和/或someY,以及是否存在此類引用。在執行f()時,可能會偶然使用對同一對象的非const引用;并且編譯器甚至可能根本不知道x和someY僅僅是引用的實際對象是否實際上首先聲明為const。


案例3:


  void f( const Z z )

  {

    // ...

  }

Ques =>會不會有任何優化?


是的,因為編譯器知道z確實是一個const對象,所以即使沒有全局分析它也可以執行一些有用的優化。例如,如果f()的主體包含類似g(&z)的調用,則編譯器可以確保z的不可更改部分在調用g()時不會發生變化。


查看完整回答
反對 回復 2019-11-18
?
狐的傳說

TA貢獻1804條經驗 獲得超3個贊

在給出任何答案之前,我想強調指出,const真正使用或不使用的原因應該是為了程序正確性和其他開發人員的清晰度,而不是編譯器優化。也就是說,使參數const記錄該方法將不會修改該參數,而使成員函數const記錄該成員將不會修改該對象是其成員的對象(至少不會以邏輯方式更改任何對象的輸出)其他const成員函數)。例如,這樣做可以使開發人員避免制作不必要的對象副本(因為他們不必擔心原始對象將被破壞或修改)或避免不必要的線程同步(例如,通過知道所有線程僅讀取并執行)不會使相關對象發生變異)。


就優化而言,至少在理論上,編譯器可以采用優化模式,盡管允許其做出可能破壞標準C ++代碼的某些非標準假設,但請考慮以下因素:


for (int i = 0; i < obj.length(); ++i) {

   f(obj);

}

假設該length函數被標記為,const但實際上是一個昂貴的操作(假設它實際上以O(n)時間而不是O(1)時間運行)。如果函數f通過const引用獲取其參數,則編譯器可能會優化此循環以:


int cached_length = obj.length();

for (int i = 0; i < cached_length; ++i) {

   f(obj);

}

...因為函數f不會修改參數這一事實保證了在length給定對象未更改的情況下,函數每次應返回相同的值。但是,如果f通過可變引用聲明要接受參數,length則將需要在循環的每次迭代中重新計算,因為f可能已經修改了對象,從而產生了值的變化。


如評論中所指出的那樣,這假設了許多其他警告,并且僅在以非標準模式調用編譯器時才可能實現,該模式允許編譯器做出其他假設(例如,const方法嚴格取決于其輸入和輸出的函數)。優化可以假定代碼將永遠不會使用const_cast將const引用參數轉換為可變引用)。


查看完整回答
反對 回復 2019-11-18
  • 3 回答
  • 0 關注
  • 688 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號