Linux fority source和__builtin_xxx

這段代碼是用于啟用和配置 GCC/Clang 的 Fortify Source 安全機制的預處理指令。Fortify Source 主要用于在編譯時增強對緩沖區溢出等內存安全問題的檢查。以下是對每一部分的詳細解釋:


1. 最外層條件編譯

#  if CONFIG_FORTIFY_SOURCE > 0
  • 目的:檢查是否啟用了 Fortify Source(通過 CONFIG_FORTIFY_SOURCE 的值判斷)。
  • 如果 CONFIG_FORTIFY_SOURCE 的值大于 0,則啟用下面的代碼邏輯。

2. 檢查優化等級

#    if !defined(__OPTIMIZE__) || (__OPTIMIZE__) <= 0
#      warning requires compiling with optimization (-O2 or higher)
#    endif
  • 目的:確保編譯時啟用了優化(-O2 或更高)。
  • Fortify Source 依賴編譯器優化才能生效。如果未啟用優化(__OPTIMIZE__ 未定義或值小于等于 0),會發出警告。

3. 處理 CONFIG_FORTIFY_SOURCE == 3

#    if CONFIG_FORTIFY_SOURCE == 3
#      if __GNUC__ < 12 || (defined(__clang__) && __clang_major__ < 12)
#        error compiler version less than 12 does not support dynamic object size
#      endif
  • 目的:當 Fortify Source 配置為 3 時,檢查編譯器版本是否支持動態對象大小檢查。
  • CONFIG_FORTIFY_SOURCE == 3 表示啟用動態對象大小檢查(更嚴格的檢查)。
  • 需要 GCC ≥12 或 Clang ≥12,否則報錯(舊版本不支持 __builtin_dynamic_object_size)。

4. 定義 fortify_size

#      define fortify_size(__o, type) __builtin_dynamic_object_size(__o, type)
#    else
#      define fortize_size(__o, type) __builtin_object_size(__o, type)
#    endif
  • 目的:根據配置選擇靜態或動態對象大小檢查。
    • CONFIG_FORTIFY_SOURCE == 3,使用 __builtin_dynamic_object_size(動態計算對象大小)。
    • 其他情況使用 __builtin_object_size(靜態編譯時計算對象大小)。
  • 這兩個內置函數用于獲取緩沖區的大小,幫助檢測緩沖區溢出。

5. 定義 fortify_assert

#    define fortify_assert(condition) do { \if (!(condition)) { \__builtin_trap(); \} \} while (0)
  • 目的:在條件不滿足時觸發程序終止。
  • 如果斷言失敗(condition 為假),調用 __builtin_trap() 立即終止程序(防止安全漏洞被利用)。

6. 定義 fortify_va_arg_pack

#    define fortify_va_arg_pack __builtin_va_arg_pack
  • 目的:處理可變參數函數(如 printf)。
  • __builtin_va_arg_pack 是 GCC 的內置函數,用于獲取可變參數列表,用于對可變參數函數進行安全檢查。

7. 定義 fortify_real

#    define fortify_real(fn) __typeof__(fn) __real_##fn __asm__(#fn)
  • 目的:聲明原始函數的別名。
  • 例如,fortify_real(memcpy) 會生成 __real_memcpy,指向原始的 memcpy 函數。
  • 這是為了在替換標準庫函數時保留原始函數的入口。

8. 定義 fortify_function

#    define fortify_function(fn) fortify_real(fn); \extern __inline__ no_builtin(#fn) \__attribute__((__always_inline__, __gnu_inline__, __artificial__))
  • 目的:定義內聯的強化版函數。
  • no_builtin(#fn):禁用編譯器對 fn 的內置實現(強制使用自定義實現)。
  • 屬性說明:
    • __always_inline__:強制內聯展開。
    • __gnu_inline__:兼容 GNU 內聯規則。
    • __artificial__:告訴調試器這是“人工”函數(調試時隱藏實現細節)。

總結

這段代碼的作用是:

  1. 啟用 Fortify Source:通過條件編譯和宏定義,替換標準庫函數(如 memcpy, strcpy 等)。
  2. 安全檢查:在編譯時和運行時插入緩沖區大小檢查,防止內存安全問題。
  3. 兼容性處理:根據編譯器版本和優化等級調整實現方式。

典型應用場景是 Linux 內核或安全敏感項目,用于增強代碼的安全性。

---------------------------------------------------------------------------

這個 fortify_real 宏的作用是為原始函數創建一個別名,使得在替換標準庫函數(如 memcpy, strcpy 等)時,仍能保留對原始函數的調用入口。這是 Fortify Source 實現安全檢查的關鍵機制。我們逐層解剖它的語法和用途:


宏定義分解

#    define fortify_real(fn) __typeof__(fn) __real_##fn __asm__(#fn)
1. __typeof__(fn)
  • 作用:獲取函數 fn 的類型(返回值類型 + 參數類型)。
  • 例如,如果 fnmemcpy(聲明為 void* memcpy(void*, const void*, size_t)),則 __typeof__(fn) 會被替換為 void* (*)(void*, const void*, size_t)(即函數指針類型)。

2. __real_##fn
  • 作用:通過 ##(預處理器粘貼符)生成一個名為 __real_函數名 的新標識符。
  • 例如,若 fnmemcpy,則 __real_##fn 會展開為 __real_memcpy
  • 用途:這個新名稱將作為原始函數的別名,避免與自定義的強化函數沖突。

3. __asm__(#fn)
  • 作用:通過 __asm__(GCC/Clang 的內聯匯編擴展)指定符號的匯編名稱。
  • #fn 會將 fn 字符串化(例如,memcpy"memcpy")。
  • 最終效果:將 __real_memcpy 這個符號與原始函數 memcpy 的匯編符號綁定。
    • 相當于告訴編譯器:“__real_memcpy 這個變量/函數,在匯編層對應符號 memcpy”。

完整展開示例

假設調用 fortify_real(memcpy),宏會展開為:

__typeof__(memcpy) __real_memcpy __asm__("memcpy");

這相當于:

// 1. 獲取 memcpy 的類型(假設為標準庫聲明)
typedef void* (*memcpy_type)(void*, const void*, size_t);// 2. 聲明一個函數指針變量 __real_memcpy,并綁定到符號 "memcpy"(即原始 memcpy)
memcpy_type __real_memcpy __asm__("memcpy");

實際用途

在 Fortify Source 中,這個宏的典型用法是替換標準庫函數,同時保留原始函數的調用方式。例如:

// 1. 聲明原始 memcpy 的別名 __real_memcpy
fortify_real(memcpy);// 2. 定義強化版的 memcpy
void* memcpy(void* dest, const void* src, size_t n) {// 檢查緩沖區大小是否合法if (n > fortify_size(dest, 1)) {__builtin_trap(); // 觸發崩潰}// 調用原始 memcpy(通過 __real_memcpy)return __real_memcpy(dest, src, n);
}
  • 關鍵點:用戶代碼調用 memcpy 時,實際調用的是強化版函數,而強化版內部通過 __real_memcpy 調用原始函數。

為什么需要這種設計?

  1. 安全增強:在調用原始函數前插入安全檢查(如緩沖區大小驗證)。
  2. 透明替換:用戶代碼無需修改,所有對 memcpy 的調用自動被重定向到強化版。
  3. 避免遞歸調用:如果沒有 __real_memcpy,強化版 memcpy 內部調用 memcpy 會導致無限遞歸。

總結

  • fortify_real 宏的本質:通過預處理器和編譯器擴展,為原始函數創建一個別名(__real_函數名),使得強化版函數能安全地調用原始實現。
  • 應用場景:安全加固的標準庫函數實現(如 Linux 內核、安全敏感項目)。

---------------------------------------------------------------------------

__builtin_dynamic_object_size__builtin_object_size 是 GCC/Clang 提供的兩個內置函數(built-in functions),用于在編譯時或運行時計算對象(如緩沖區)的大小。它們的主要區別在于計算方式的靈活性適用場景,以下是詳細對比:


1. __builtin_object_size靜態對象大小計算

  • 功能
    編譯時嘗試計算對象(如數組或指針指向的緩沖區)的靜態已知大小
  • 語法
    size_t __builtin_object_size(const void* ptr, int type);
    
    • ptr:需要計算大小的對象指針。
    • type:取值范圍 0123,控制計算邏輯:
      • type & 1:是否假設 ptr 指向的對象是子對象(如結構體成員)。
      • type & 2:是否在無法確定大小時返回安全的最小值(0)或最大值(SIZE_MAX)。
  • 局限性
    • 僅能在編譯時確定大小(依賴優化等級 -O1 或更高)。
    • 對于動態分配的內存(如 malloc)或復雜指針運算,可能無法正確計算,返回 SIZE_MAX0
示例
char buf[10];
size_t size = __builtin_object_size(buf, 0); // 返回 10char* p = malloc(20);
size_t size_p = __builtin_object_size(p, 0); // 可能返回 0 或 SIZE_MAX(取決于優化和代碼結構)

2. __builtin_dynamic_object_size動態對象大小計算

  • 功能
    運行時動態計算對象的大小,支持更復雜場景(如動態分配的內存、變量長度數組等)。
  • 語法
    size_t __builtin_dynamic_object_size(const void* ptr, int type);
    
    • 參數 type 的語義與 __builtin_object_size 相同。
  • 優勢
    • 可以處理編譯時無法確定大小的對象(如通過 alloca、VLA 分配的緩沖區)。
    • 更精確的安全檢查(例如檢測 strcpy 寫入是否超出實際分配的內存)。
示例
void func(size_t n) {char buf[n]; // 變量長度數組(VLA)size_t size = __builtin_dynamic_object_size(buf, 0); // 返回 n
}

關鍵區別總結

特性__builtin_object_size__builtin_dynamic_object_size
計算時機編譯時(依賴優化等級)運行時(動態計算)
動態內存支持有限(如 malloc 可能失敗)支持(如 alloca、VLA)
編譯器要求較舊版本(GCC 4.1+)需要較新版本(GCC 12+ 或 Clang 12+)
準確性依賴編譯時可分析性更靈活,適用于運行時場景
Fortify Source 應用CONFIG_FORTIFY_SOURCE=1/2CONFIG_FORTIFY_SOURCE=3(更嚴格模式)

具體應用場景

場景 1:靜態數組
char static_buf[100];
size_t s1 = __builtin_object_size(static_buf, 0);    // 返回 100
size_t s2 = __builtin_dynamic_object_size(static_buf, 0); // 同樣返回 100
  • 兩者結果一致,因為大小在編譯時已知。
場景 2:動態分配內存
void foo(size_t n) {char* dynamic_buf = malloc(n);size_t s1 = __builtin_object_size(dynamic_buf, 0);      // 可能返回 0 或 SIZE_MAXsize_t s2 = __builtin_dynamic_object_size(dynamic_buf, 0); // 返回實際分配的 n
}
  • __builtin_object_size 無法跟蹤 malloc 的運行時參數,而 __builtin_dynamic_object_size 可以。
場景 3:變量長度數組(VLA)
void bar(size_t n) {char vla_buf[n];size_t s1 = __builtin_object_size(vla_buf, 0);      // 可能返回 0(編譯時無法確定)size_t s2 = __builtin_dynamic_object_size(vla_buf, 0); // 返回 n
}
  • __builtin_dynamic_object_size 是唯一能正確處理 VLA 的選項。

在 Fortify Source 中的作用

  • CONFIG_FORTIFY_SOURCE=1/2
    使用 __builtin_object_size,在編譯時插入靜態檢查。例如:

    char buf[10];
    strcpy(buf, "overflow!"); // 編譯時報錯(靜態檢查到溢出)
    
  • CONFIG_FORTIFY_SOURCE=3
    使用 __builtin_dynamic_object_size,在運行時插入動態檢查。例如:

    void func(size_t n) {char* buf = malloc(n);read(fd, buf, n+1); // 運行時檢查:若實際寫入超過 n,觸發崩潰
    }
    

總結

  • __builtin_object_size:適合簡單場景,依賴編譯時優化,但對動態內存支持有限。
  • __builtin_dynamic_object_size:更強大靈活,支持運行時計算,但需要新版本編譯器。

Fortify Source 通過這兩者的組合,實現了從靜態到動態的多層次內存安全防護。

---------------------------------------------------------------------------

__builtin_trap 是 GCC 和 Clang 等編譯器提供的一個內置函數(built-in function),它的核心作用是立即終止程序執行,并觸發一個與平臺相關的硬件異常或信號。以下是它的詳細行為、用途和與其他類似函數的對比:


1. 核心功能

  • 作用
    當調用 __builtin_trap() 時,編譯器會生成一條特定的陷阱指令(如 ud2 在 x86 架構,或 trap 在某些 RISC 架構),導致程序立即終止。
  • 終止方式
    • 在類 Unix 系統(Linux/macOS)中,通常會觸發 SIGILL 信號(非法指令)或 SIGTRAP 信號。
    • 在 Windows 中,可能觸發結構化異常(SEH)的非法指令異常。
  • 結果
    程序崩潰,生成核心轉儲(core dump,如果系統允許),不會執行后續代碼。

2. 典型使用場景

(1) 不可恢復的錯誤處理

用于標記代碼中的“不可能到達”的分支或未處理的錯誤條件。例如:

switch (value) {case 1: do_something(); break;case 2: do_another(); break;default: __builtin_trap(); // 如果 value 只能是 1 或 2,此處標記邏輯錯誤
}
(2) 安全防護(Fortify Source)

在安全敏感代碼中,檢測到緩沖區溢出等漏洞時立即終止程序,防止攻擊者利用漏洞:

if (buffer_overflow_condition) {__builtin_trap(); // 主動崩潰,拒絕繼續執行危險操作
}
(3) 調試輔助

強制程序在特定位置崩潰,方便通過核心轉儲或調試器定位問題。


3. 與其他終止函數的對比

函數/機制行為可捕獲性適用場景
__builtin_trap()生成陷阱指令,直接觸發硬件異常不可捕獲(直接硬件異常)安全防護、邏輯錯誤終止
abort()發送 SIGABRT 信號,默認終止進程可捕獲(通過信號處理)一般錯誤終止
exit()正常退出,執行清理函數(如 atexit 注冊的函數)正常退出資源釋放后退出
assert()若斷言失敗,調用 abort()可捕獲調試期斷言
panic()(內核)內核級錯誤處理,記錄信息后停機系統級崩潰操作系統內核崩潰

4. 關鍵特性

(1) 不可恢復性
  • 無法通過信號處理函數(如 signal(SIGTRAP, handler))攔截或恢復執行。
  • abort() 不同,SIGABRT 可被捕獲并嘗試恢復,但 __builtin_trap() 直接觸發硬件異常,更“強硬”。
(2) 編譯器優化
  • 編譯器會將 __builtin_trap() 視為不可達代碼(unreachable code),可能優化其后的代碼。例如:
    if (error) {__builtin_trap();
    }
    safe_code(); // 編譯器可能認為此處永遠不會被執行,從而優化掉某些檢查
    
(3) 跨平臺行為
  • Linux/macOS:通常生成 SIGILL(非法指令)信號。
  • Windows:觸發 STATUS_ILLEGAL_INSTRUCTION 異常。
  • 嵌入式系統:可能導致硬件復位或進入調試模式。

5. 示例代碼

場景:檢測緩沖區溢出
#include <string.h>void fortified_memcpy(void* dest, const void* src, size_t n) {// 動態檢查目標緩沖區大小size_t dest_size = __builtin_dynamic_object_size(dest, 1);if (n > dest_size) {__builtin_trap(); // 溢出風險,立即終止}memcpy(dest, src, n);
}

6. 注意事項

  1. 調試友好性
    使用 __builtin_trap() 生成的崩潰會保留完整的調用棧和核心轉儲,方便事后分析。

  2. unreachable() 的區別
    __builtin_unreachable() 僅提示編譯器代碼不可達(用于優化),而 __builtin_trap() 會實際生成終止指令。

  3. 不可濫用
    僅在確實需要主動防御安全漏洞或標記邏輯錯誤時使用,過度使用會降低程序健壯性。


總結

__builtin_trap() 是編譯器提供的一種“強硬”終止機制,適合以下場景:

  • 安全敏感代碼:檢測到漏洞時立即終止,防止攻擊者利用。
  • 邏輯完整性檢查:標記理論上不應出現的代碼分支。
  • 調試輔助:在關鍵路徑上強制崩潰,定位問題。

它的不可捕獲性和直接觸發硬件異常的特性,使其成為安全加固代碼中的重要工具。

---------------------------------------------------------------------------

__builtin_object_sizetype 參數是一個整數,取值范圍為 0123,它通過 低兩位比特(bit 0 和 bit 1) 的組合控制計算對象大小的行為。以下是每個 type 值的詳細解釋:


type 參數的定義

type 的低兩位比特決定了以下行為:

  1. 最低位(bit 0)
    • 0:假設 ptr 指向一個完整的對象(不考慮子對象)。
    • 1:假設 ptr 可能指向一個子對象(如結構體成員或數組元素)。
  2. 次低位(bit 1)
    • 0:在無法確定對象大小時,返回 安全的最小可能值(保守模式)。
    • 1:在無法確定對象大小時,返回 安全的最大可能值(寬松模式)。

因此,type 的四種組合如下:

typebit 1bit 0行為模式
000保守模式:不考慮子對象,無法確定大小時返回最小值(通常 0)。
101保守模式:考慮子對象,無法確定大小時返回最小值。
210寬松模式:不考慮子對象,無法確定大小時返回最大值(通常 SIZE_MAX)。
311寬松模式:考慮子對象,無法確定大小時返回最大值。

具體行為詳解

1. type = 0(保守模式,不考慮子對象)
  • 行為
    嘗試計算 ptr 指向的 完整對象 的大小。若無法確定,返回 0
  • 適用場景
    嚴格的緩沖區溢出檢查,例如確保 memcpy 不會溢出目標緩沖區。
  • 示例
    char buf[10];
    size_t size = __builtin_object_size(buf, 0); // 返回 10struct Example {char header[4];char data[20];
    } obj;
    size_t size_header = __builtin_object_size(obj.header, 0); // 返回 4(完整對象是 header)
    size_t size_data = __builtin_object_size(obj.data, 0);     // 返回 20(完整對象是 data)
    

2. type = 1(保守模式,考慮子對象)
  • 行為
    嘗試計算 ptr 指向的 子對象 所屬的父對象的大小。若無法確定,返回 0
  • 適用場景
    ptr 可能指向一個子對象(如結構體成員)時,檢查父對象的總大小。
  • 示例
    struct Example {char header[4];char data[20];
    } obj;char* p = obj.data;
    size_t size = __builtin_object_size(p, 1); // 返回 20(父對象是 data)// 若 type=0,則返回 20(完整對象是 data)
    

3. type = 2(寬松模式,不考慮子對象)
  • 行為
    嘗試計算 ptr 指向的 完整對象 的大小。若無法確定,返回 SIZE_MAX
  • 適用場景
    允許最大可能的緩沖區大小,避免誤報(例如動態內存分配時)。
  • 示例
    char* p = malloc(100);
    size_t size = __builtin_object_size(p, 2); // 可能返回 SIZE_MAX(無法靜態確定大小)char buf[10];
    size = __builtin_object_size(buf, 2);      // 返回 10
    

4. type = 3(寬松模式,考慮子對象)
  • 行為
    嘗試計算 ptr 指向的 子對象 所屬的父對象的大小。若無法確定,返回 SIZE_MAX
  • 適用場景
    允許動態內存或復雜指針結構的最大可能大小。
  • 示例
    struct Example {char header[4];char data[20];
    } obj;char* p = obj.data + 5; // 指向 data 的中間位置
    size_t size = __builtin_object_size(p, 3); // 返回 15(剩余空間:20 - 5 = 15)
    

關鍵區別總結

type模式子對象處理無法確定時返回值典型場景
0保守模式不考慮子對象0嚴格檢查靜態緩沖區溢出
1保守模式考慮子對象0檢查結構體成員的父對象大小
2寬松模式不考慮子對象SIZE_MAX避免誤報動態內存操作
3寬松模式考慮子對象SIZE_MAX動態內存或復雜指針結構的檢查

實際應用示例

場景:安全增強的 memcpy
void safe_memcpy(void* dest, const void* src, size_t n) {// 使用 type=0(保守模式,不考慮子對象)size_t dest_size = __builtin_object_size(dest, 0);if (n > dest_size) {__builtin_trap(); // 終止程序}memcpy(dest, src, n);
}
場景:動態分配的緩沖區
void process_data(size_t len) {char* buf = malloc(len);// 使用 type=2(寬松模式,不考慮子對象)size_t buf_size = __builtin_object_size(buf, 2);if (buf_size != SIZE_MAX && buf_size < len) {__builtin_trap();}// 安全操作...
}

注意事項

  1. 編譯器依賴
    具體行為可能因編譯器版本和優化等級(-O1 或更高)而異。例如,malloc(100) 在編譯時可能被推斷為固定大小。
  2. 動態內存限制
    malloc/new 分配的動態內存,__builtin_object_size 通常無法準確計算大小(返回 0SIZE_MAX)。
  3. 子對象場景
    ptr 指向子對象(如結構體成員)時,type=13 可以計算父對象的總大小。

總結

  • type=0type=1:用于嚴格的安全檢查(返回最小值)。
  • type=2type=3:用于避免誤報(返回最大值)。
  • 根據是否需要考慮子對象和是否容忍不確定性,選擇合適的 type 值。

---------------------------------------------------------------------------

你的問題涉及編譯器內置函數(Compiler Built-ins)的本質和實現細節,以下是分層次的解答:


1. __builtin_xx 是什么?

  • 官方定義
    這些是 GCC/Clang 等編譯器直接提供的內置函數(Built-in Functions),屬于編譯器的私有擴展,并非標準 C/C++ 的一部分。
  • 作用
    提供底層硬件操作、優化提示或語言無法直接表達的功能(如對象大小計算、陷阱指令生成等)。
  • 命名規則
    __builtin_ 前綴開頭,表示它們是編譯器“自帶”的特殊功能。

2. 與用戶自定義函數的區別

特性__builtin_xx用戶自定義函數
實現方編譯器內部實現用戶代碼或庫文件
編譯階段處理直接翻譯為特定指令或優化行為(無函數調用)生成函數調用指令(可能被內聯優化)
可見性無源碼(編譯器魔法)可查看源碼
可移植性依賴編譯器(GCC/Clang/ICC 等)標準 C/C++ 代碼可跨平臺
性能零開銷(如 __builtin_trap() 生成單條指令)可能有調用開銷

3. 為什么需要內置函數?

  • 訪問硬件特性
    例如 __builtin_prefetch(緩存預取)、__builtin_ia32_rdtsc(讀取時間戳計數器)。
  • 優化控制
    例如 __builtin_expect(分支預測提示)、__builtin_unreachable(標記不可達代碼)。
  • 安全增強
    例如 __builtin_object_size(緩沖區檢查)、__builtin_trap(快速終止)。
  • 語言擴展
    例如 __builtin_va_arg(可變參數處理)、__builtin_offsetof(結構體成員偏移)。

4. 能否看到實現代碼?

  • 不能直接查看
    內置函數的邏輯 直接內置于編譯器內部(GCC/Clang 的源代碼中),沒有用戶可見的 C/C++ 實現代碼。
  • 間接研究方式
    1. 編譯器源碼
      例如 GCC 的 gcc/builtins.def 定義了內置函數的行為,但需要熟悉編譯器開發。
    2. 反匯編
      通過編譯生成的匯編代碼觀察其行為(例如 gcc -S 輸出):
      // 示例:__builtin_trap() 的匯編輸出(x86)
      ud2;    // 生成非法指令
      
    3. 文檔
      GCC 官方文檔 描述了每個內置函數的行為。

5. 常見 __builtin_xx 示例

內置函數作用等效用戶代碼可能性
__builtin_memcpy優化版內存拷貝可實現,但性能更差
__builtin_expect分支預測優化(如 likely/unlikely無法用 C 代碼實現
__builtin_popcount計算整數二進制中 1 的個數可實現,但更慢
__builtin_debugtrap調試斷點(不終止程序)依賴平臺特定匯編
__builtin_constant_p判斷表達式是否為編譯時常量無法實現

6. 用戶如何模擬內置函數?

某些內置函數的功能可以通過其他方式近似實現,但通常性能或安全性更差:

  • 示例 1:__builtin_trap 的替代

    // 用戶模擬版本(不跨平臺)
    void my_trap() {*((volatile int*)0) = 0; // 觸發段錯誤(SIGSEGV)
    }
    

    缺點:信號可被捕獲,不如 __builtin_trap() 直接。

  • 示例 2:__builtin_popcount 的替代

    int my_popcount(unsigned int x) {int count = 0;while (x) {count += x & 1;x >>= 1;}return count;
    }
    

    缺點:編譯器無法優化為單條 POPCNT 指令。


7. 為什么編譯器不開放實現?

  • 硬件依賴性
    某些內置函數直接映射到特定 CPU 指令(如 __builtin_ia32_rdtsc)。
  • 優化耦合性
    內置函數的行為可能與編譯器的中間表示(IR)優化深度綁定。
  • 避免濫用
    這些函數通常用于編譯器或標準庫開發,普通用戶應優先使用標準庫接口。

8. 何時應該使用內置函數?

  • 需要極致性能(如加密算法中的 __builtin_aes)。
  • 實現標準庫(如 glibcmemcpy__builtin_memcpy 優化)。
  • 系統級開發(如內核中需要觸發陷阱或讀取寄存器)。
  • 安全關鍵代碼(如 Fortify Source 的緩沖區檢查)。

總結

  • __builtin_xx 是編譯器的“黑魔法”,沒有用戶可見的實現代碼,但可通過文檔和反匯編理解其行為。
  • 與用戶函數相比,它們零開銷、與硬件/優化深度集成,但犧牲了可移植性。
  • 普通開發中應優先使用標準庫,僅在必要時謹慎使用內置函數。

示例代碼參考
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74356.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74356.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74356.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL GROUP BY 自定義排序規則

在 SQL 中&#xff0c;GROUP BY 子句用于將結果集按一個或多個列進行分組。默認情況下&#xff0c;GROUP BY 會按照列的自然順序&#xff08;如字母順序或數字順序&#xff09;進行排序。如果你需要按照自定義的排序規則對結果進行分組&#xff0c;可以使用 ORDER BY 子句結合 …

語言模型理論基礎-持續更新-思路清晰

1.預訓練 相似的任務A、B&#xff0c;任務A已經用大數據完成了訓練&#xff0c;得到模型A。 我們利用-特征提取模型的-“淺層參數通用”的特性&#xff0c;使用模型A的淺層參數&#xff0c;其他參數再通過任務B去訓練&#xff08;微調&#xff09;。 2.統計語言模型 通過條件…

ResNet與注意力機制:深度學習中的強強聯合

引言 在深度學習領域&#xff0c;卷積神經網絡&#xff08;CNN&#xff09;一直是圖像處理任務的主流架構。然而&#xff0c;隨著網絡深度的增加&#xff0c;梯度消失和梯度爆炸問題逐漸顯現&#xff0c;限制了網絡的性能。為了解決這一問題&#xff0c;ResNet&#xff08;殘差…

【C++】——C++11新特性

目錄 前言 1.初始化列表 2.std::initializer_list 3.auto 4.decltype 5.nullptr 6.左值引用和右值引用 6.1右值引用的真面目 6.2左值引用和右值引用比較 6.3右值引用的意義 6.3.1移動構造 6.4萬能引用 6.5完美轉發——forward 結語 前言 C&#xff0c;這門在系統…

【C++網絡編程】第5篇:UDP與廣播通信

一、UDP協議核心特性 1. UDP vs TCP ?特性 ?UDP?TCP連接方式無連接面向連接&#xff08;三次握手&#xff09;可靠性不保證數據到達或順序可靠傳輸&#xff08;超時重傳、順序控制&#xff09;傳輸效率低延遲&#xff0c;高吞吐相對較低&#xff08;因握手和確認機制&…

MOSN(Modular Open Smart Network)是一款主要使用 Go 語言開發的云原生網絡代理平臺

前言 大家好&#xff0c;我是老馬。 sofastack 其實出來很久了&#xff0c;第一次應該是在 2022 年左右開始關注&#xff0c;但是一直沒有深入研究。 最近想學習一下 SOFA 對于生態的設計和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概覽 SOFABoot-01-螞蟻金服開源的 s…

微信小程序日常開發問題整理

微信小程序日常開發問題整理 1 切換渲染模式1.1 WebView 的鏈接在模擬器可以打開&#xff0c;手機上無法打開。 1 切換渲染模式 1.1 WebView 的鏈接在模擬器可以打開&#xff0c;手機上無法打開。 在 app.json 中看到如下配置項&#xff0c;那么當前項目就是 keyline 渲染模式…

【Altium Designer】銅皮編輯

一、動態銅皮與靜態銅皮的區分與切換 動態銅皮&#xff08;活銅&#xff09;&#xff1a; 通過快捷鍵 PG 創建&#xff0c;支持自動避讓其他網絡對象&#xff0c;常用于大面積鋪銅&#xff08;如GND或電源網絡&#xff09;。修改動態銅皮后&#xff0c;需通過 Tools → Polygo…

Java「Deque」 方法詳解:從入門到實戰

Java Deque 各種方法解析&#xff1a;從入門到實戰 在 Java 編程中&#xff0c;Deque&#xff08;雙端隊列&#xff09;是一個功能強大的數據結構&#xff0c;允許開發者從隊列的兩端高效地添加、刪除和檢查元素。作為 java.util 包中的一部分&#xff0c;Deque 接口繼承自 Qu…

ffmpeg+QOpenGLWidget顯示視頻

?一個基于 ?FFmpeg 4.x? 和 QOpenGLWidget的簡單視頻播放器代碼示例&#xff0c;實現視頻解碼和渲染到 Qt 窗口的功能。 1&#xff09;ffmpeg庫界面&#xff0c;視頻解碼支持軟解和硬解方式。 硬解后&#xff0c;硬件解碼完成需要將數據從GPU復制到CPU。優先采用av_hwf…

深入解析嵌入式內核:從架構到實踐

一、嵌入式內核概述 嵌入式內核是嵌入式操作系統的核心組件&#xff0c;負責管理硬件資源、調度任務、處理中斷等關鍵功能。其核心目標是在資源受限的環境中提供高效、實時的控制能力。與通用操作系統不同&#xff0c;嵌入式內核通常具有高度可裁剪性、實時性和可靠性&#xff…

20250324-使用 `nltk` 的 `sent_tokenize`, `word_tokenize、WordNetLemmatizer` 方法時報錯

解決使用 nltk 的 sent_tokenize, word_tokenize、WordNetLemmatizer 方法時報錯問題 第 2 節的手動方法的法1可解決大部分問題&#xff0c;可首先嘗試章節 2 的方法 1. nltk.download(‘punkt_tab’) LookupError: *******************************************************…

『 C++ 』多線程同步:條件變量及其接口的應用實踐

文章目錄 條件變量概述條件變量簡介條件變量的基本用法 案例&#xff1a;兩個線程交替打印奇偶數代碼解釋 std::unique_lock::try_lock_until 介紹代碼示例代碼解釋注意事項 std::condition_variable::wait 詳細解析與示例std::condition_variable::wait 接口介紹代碼示例代碼解…

【VolView】純前端實現CT三維重建-CBCT

文章目錄 什么是CBCTCBCT技術路線使用第三方工具使用Python實現使用前端實現 純前端實現方案優缺點使用VolView實現CBCT VolView的使用1.克隆代碼2.配置依賴3.運行4.效果 進階&#xff1a;VolView配合Python解決卡頓1.修改VtkThreeView.vue2.新增Custom3DView.vue3.Python生成s…

debug - 安裝.msi時,為所有用戶安裝程序

文章目錄 debug - 安裝.msi時&#xff0c;為所有用戶安裝程序概述筆記試試在目標.msi后面直接加參數的測試 備注備注END debug - 安裝.msi時&#xff0c;為所有用戶安裝程序 概述 為了測試&#xff0c;裝了一個test.msi. 安裝時&#xff0c;只有安裝路徑的選擇&#xff0c;沒…

Java Stream兩種list判斷字符串是否存在方案

這里寫自定義目錄標題 背景初始化方法一、filter過濾方法二、anyMatch匹配 背景 在項目開發中&#xff0c;經常遇到篩選list中是否包含某個子字符串&#xff0c;有多種方式&#xff0c;本篇主要介紹stream流的filter和anyMatch兩種方案&#xff0c;記錄下來&#xff0c;方便備…

DeepSeek vs 通義大模型:誰將主導中國AI的未來戰場?

當你在深夜調試代碼時,是否幻想過AI伙伴能真正理解你的需求?當企業面對海量數據時,是否期待一個真正智能的決策大腦? 這場由DeepSeek和通義領銜的大模型之爭,正在重塑中國AI產業的競爭格局。本文將為你揭開兩大技術巨頭的終極對決! 一、顛覆認知的技術突破 1.1 改變游戲…

3. 軸指令(omron 機器自動化控制器)——>MC_SetOverride

機器自動化控制器——第三章 軸指令 12 MC_SetOverride變量?輸入變量?輸出變量?輸入輸出變量 功能說明?時序圖?重啟運動指令?多重啟動運動指令?異常 MC_SetOverride 變更軸的目標速度。 指令名稱FB/FUN圖形表現ST表現MC_SetOverride超調值設定FBMC_SetOverride_instan…

從像素到世界:自動駕駛視覺感知的坐標變換體系

接著上一篇 如何讓自動駕駛汽車“看清”世界?坐標映射與數據融合詳解的概述,這一篇詳細講解自動駕駛多目視覺系統設計原理,并給出應用示例。 摘要 在自動駕駛系統中,準確的環境感知是實現路徑規劃與決策控制的基礎。本文系統性地解析圖像坐標系、像素坐標系、相機坐標系與…

附錄B ISO15118-20測試命令

本章節給出ISO15118-20協議集的V2G命令&#xff0c;包含json、xml&#xff0c;并且根據exiCodec.jar編碼得到exi內容&#xff0c; 讀者可以參考使用&#xff0c;測試編解碼庫是否能正確編解碼。 B.1 supportedAppProtocolReq json: {"supportedAppProtocolReq": {…