從編譯器角度看 lambda表示式

2021-09-25 14:21:11 字數 2050 閱讀 6209

lambda轉換為函式物件。

現在,android已經全面轉向c++11/14標準了,看**的話,很多地方變化很大,新標準真的是有點顛覆性的,感覺已經不會c++了。今天有看到lambda表示式,突然想看一下,這貨是怎麼實現的,如下,寫了個例子,分別呼叫3個lambda表示式:

#include

#include

//1. 無引數

auto hello = () ;

// 2. 乙個引數

auto hello_int = (intval);

intmain(intargc,char**ar**) ;

lambda();

return0;

}

很簡單定義三個lambda表示式,lambda表示式就不細說是什麼了,基本上是介紹新標準的書,都會說的很明白。這裡想看一下,具體編譯器是怎麼實現表示式的呢?第一印象,應該是表示式按照內聯函式的方式實現的吧,呼叫的地方自動展開,這樣引數、捕獲列表啥的都很好實現。

簡單看一下,編譯時不優化,反彙編看一下,如下,呼叫的main函式:

上面按順序呼叫的,就是**中對應的三個lambda表示式。從這個反彙編看,貌似和猜想的不一樣是調了函式不是內聯展開。

紅色框住的呼叫函式[藍色是實際的符號,灰色是demangle後的,分析看這個],分別是:?

$_0::operator()(void)

$_1::operator()(int)

main::$_2::operator()const(void)

這是三個過載的()操作符.. 呼叫前看到有壓入this引數,這是物件的方法呼叫,從反彙編看,是棧上建立物件,然後直接使用,使用是通過operator()..

這貨不就是函式物件麼????

ok,那就明白了,lambda表示式,編譯器自動轉換成函式物件執行。。。。

上面的例子,編譯器轉換的如下:?

#include

#include

class$_0

};

class$_1

};

classmain::$_2

//帶捕獲列表的,不能修改捕獲列表...

voidoperator()const

private:

intargc;

char**ar**;

}

intmain(intargc,char**ar**)

這裡,lambda轉換後的符號,是編譯器自動生成的,看起來稍有點彆扭。

從hello world 看編譯器原理

vim hello.c include intmain gcc o hello hello.c gcc編譯器驅動程式讀取hello.c,將其翻譯成可執行的目標檔案 hello預處理階段 hello.c 通過 cpp 改寫為 hello.i 將標頭檔案 include 引入程式當中。編譯階段 將 he...

編譯器角度看C 複製建構函式

關於複製建構函式的簡單介紹,可以看我以前寫過的一篇文章 複製控制之複製建構函式該文章中介紹了複製建構函式的定義 呼叫時機 也對編譯器合成的複製建構函式行為做了簡單說明。本文因需要會涉及到上文的一些知識點,但還是推薦先閱讀上文。本文主要從編譯器角度對複製建構函式進行分析,糾正以前對複製建構函式的一些錯...

從編譯器角度理解虛函式和繼承

在c 中,繼承的概念可以理解為c中得巢狀結構體,對於各種函式,類中的成員函式,類中的友元函式,各種繼承的虛函式,只要從編譯器的角度去理解 就會變得簡單。例如下例 class d class d1 public d class d2 public d1 函式的具體實現略 int main int ar...