深入解析std addressof

2021-10-03 17:11:43 字數 2263 閱讀 4143

std::addressof模板函式定義在標頭檔案中,用於獲取類或函式的真實位址,即使在類過載了位址操作符&的情況下也能正常工作。它有如下三個宣告:

template

<

typename t>

t*addressof

(t& arg)

noexcept

;// (1) 從c++11開始支援

template

<

typename t>

constexpr t*

addressof

(t &arg)

noexcept

;// (2) 從c++17開始支援

template

<

class

t>

const t*

addressof

(const t&&)=

delete

;// (3) 從c++17開始支援

其中arg必須是乙個左值物件或者函式。從c++17開始,在arg是乙個左值常量表示式時,addressof也保證是乙個常量表示式。常量表示式是指在編譯時就能獲得結果的表示式。宣告(3)的目的是為了阻止獲取常量右值的位址。

以下原始碼分析基於gcc 9.2.0和llvm clang 9.0.1。

/* gcc */

template

<

typename t>

inline

constexpr t*

__addressof

(t& arg)

noexcept

/* clang */

#ifndef _libcpp_has_no_builtin_addressof

template

<

class

t>

inline

constexpr t*

addressof

(t& arg)

noexcept

#else

template

<

class

t>

inline t*

addressof

(t& arg)

noexcept

#endif

// _libcpp_has_no_builtin_addressof

從實現來看,gcc和clang有些許不同。

當存在內建函式__builtin_addressof時,clang和gcc實現一樣,使用內建函式__builtin_addressof來獲取引數arg的位址。

當不存在內建函式__builtin_addressof時,clang使用reinterpret_castconst_cast組合來獲取arg的位址。為什麼要用這麼複雜的表示式來獲取位址,而不使用&arg來獲取位址呢?因為arg有可能是乙個過載了位址操作符&的類,那麼&arg就不再是取位址的語義了。

__builtin_addressofreinterpret_cast組合又有什麼不同呢?最大的不同在於__builtin_addressof是乙個常量表示式,在編譯時就能獲得表示式的值,而reinterpret_cast組合不是常量表示式。

在c++常量表示式的定義中,其中一條要求就是「常量表示式中不能有reinterpret_cast表示式」,此要求可以通過如下**進行驗證。

constexpr

int*to(

char

*p)

使用gcc編譯會提示錯誤「a reinterpret_cast is not a constant expression」,而使用clang編譯會提示錯誤「constexpr function never produces a constant expression [-winvalid-constexpr]」,這些錯誤都說明了reinterpret_cast不能產生常量表示式,也就是在有些情況下,它需要在執行時求解表示式的值。

Activity Intent深入解析

學習android sdk有段時間了,對activity intent的學習與使用都比較了解。第一次完整的學習activity intent後,我就感覺這似乎與windows com技術有些似曾相識的感覺,寫了一篇將activity 與 com 做了比較,但是一直感覺意猶未盡,前幾天在程式設計師雜誌...

深入解析IOCP

1.介紹 1.1 高併發伺服器 1 要求大規模的連線 會話可能同時進行 2 列子 web 伺服器,郵件伺服器 1.2 執行緒池架構 1 每個連線分配乙個執行緒,將導致過多的執行緒。2 執行緒消耗記憶體,比如堆疊等等。2.執行緒模型 2.1 基於會話模型 1 每個執行緒服務於乙個客戶端,比如http ...

HTTP 深入解析

1.cookie 儲存在客戶端 cookie 的類別 cookie 的屬性 了解 cookie 的應用場景 同源http請求 攜帶cookie 原生ajax請求方式 xhr.withcredentials true 支援跨域傳送cookies xhr.send jquery的ajax的post方法請...