[英]What are intrinsics?
任何人都可以解釋它們是什么以及為什么我需要它們? 如果我需要使用內在函數,我將構建什么樣的應用程序?
內部函數是編譯器在可能的情況下直接實現的函數,而不是鏈接到庫提供的函數實現。
一個常見的例子是strncpy()
。
對於短字符串,對strncpy()
進行函數調用strncpy()
包括設置帶有返回地址的“堆棧幀”)將比實際的字節復制消耗更多的時間。 更糟糕的是,對CPU預取緩沖區的影響將使CPU執行停頓幾個時鍾周期。
相反,內部函數由編譯器實現,而不是函數調用。 在strncpy()
的示例中,字節復制代碼直接在調用strncpy()
的位置發出。
與此strncpy()
示例類似,如果滿足所需的約束,則每個內部函數都直接作為內聯代碼實現。
內部函數的非內在副本通常仍然存在於標准庫中,以防需要函數的地址。
與內聯函數相比,內部函數由編譯器提供。 在C程序的源代碼中沒有寫入內部函數的地方,也沒有必須鏈接到的庫實現。 內聯函數的不同之處在於編譯器讀取內聯函數的源代碼,但類似之后,它可以將內聯函數的編譯轉換直接發送到目標代碼中,省略函數調用的開銷。
簡而言之,內部函數和內聯函數之間的實際區別在於,即使您沒有#include
包含函數聲明的必需頭文件,內部函數也“存在”。 對於內聯函數,帶有函數聲明的頭文件必須首先是#include
(或以其他方式聲明)。
通常,“內在函數”指的是內置函數 - 即大多數標准庫函數,編譯器可以/將生成內聯而不是調用庫中的實際函數。 例如,可以為x86編譯類似於: memset(array1, 10, 0)
的調用memset(array1, 10, 0)
如:
mov ecx, 10
xor eax, eax
mov edi, offset FLAT:array1
rep stosb
像這樣的內在函數純粹是一種優化。 “需要”內在函數很可能是編譯器支持內在函數的情況,這些內在函數允許您生成編譯器無法(或通常不會)直接生成的代碼。 對於一個明顯的例子,x86的很多編譯器都有“MMX內在函數”,它允許你使用“函數”,這些函數實際上只是MMX指令的直接表示。
編譯器將內在函數公開為不屬於任何庫的函數本身 。
您可能最常使用的是匯編內在函數 ,它們被編譯器視為它們所代表的機器指令。 例如,您可以在需要利用編譯器不自動生成的特定CPU指令的代碼中使用它們,並且您不一定需要完整的內聯匯編部分。
“內在函數”是編譯器識別和實現的語言的那些特性,而不需要程序來聲明它們。 編譯器可能或可能不鏈接到運行時庫以執行操作。 例如,在C ++中,結構復制操作是隱式的:
struct {
int a;
char b [100];
long c [27];
} s, t;
...
s = t; // this statement copies hundreds of bytes, likely with a rtl call
其他示例包括像Fortran這樣的語言,其中隱含支持復雜類型,並且超越(正弦,切線等)函數不需要 - 也不能聲明。 PHP,Javascript,Ruby等具有數百種內在函數,例如創建和搜索數組,執行正則表達式匹配等等。
至於你的其他問題,唯一的區別是它們是否需要申報。 例如,使用超越函數的C ++程序必須包含數學庫聲明:
#include <math.h>
沒有特定的應用程序模式依賴於內在函數; 這對編譯器編寫者和程序員來說只是一個重要的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.