在 C++ 剛出現的時候,大多數 C++ compiler 引入了一個新關鍵字 'inline' ,用於解決個體行為 (methods of object) 的部份效率瓶頸。直到 ISO C99 時,才正式將 inline 定於規範之中。不過多數的 C/C++ compiler 只將 inline 用於 C++ program 中,並未延伸到 C program (*1)。'inline' is a keyword of ANSI/ISO C99. Some C/C++ compilers do not allow to use this in C program. '__inline__' is a keyword of GNU GCC. Some compilers use '__inline'.
)。
GCC 最晚在 2.9 版 ,為 C program 加入了一個擴充關鍵字 '__inline__' (*2),使得 programmer 可以在 C program 中使用 inline function 。請參考 GNU GCC Info document setcion 'An Inline Function is As Fast As a Macro'. 說明文件意簡言骸,我將配合程式碼說明 inline function 在 C program 中運作的相關細節。
GCC 為 C program 提供了 __inline__ 擴充關鍵字,有些 compiler 則是用 __inline。
印象中,我在 1998-99 年時,便已在 C program 中使用了 __inline__ 關鍵字,見 FBTIP。因此 GCC 是在 ISO C99 規範出現前,先提供了這個擴充關鍵字供 programmer 使用。
Codes of Case
c_inline_case1.h
Case 1, combination of inline and static.
c_inline_case2.h
Case 2, combination of inline and extern.
c_inline_case3.h
Case 3, inline only.
strcase.h
case_l.c
Call inline function 'lcase' directly. 第 19 行展示了 inline function 可以回傳值的特性。用 MACRO 的方式,在此無法通過。
case_u.c
Call inline function 'ucase' via pointer of function. 第 17 行展示了 inline function 可以用於函數指標、遞迴的特性。同樣地,用 MACRO 也無法做到。
Works only in optimizing compilation
Inlining of functions is an optimization and it really "works" only in optimizing compilation. If you don't use '-O', no function is really inline.
When a function is both inline and static, if all calls to the function are integrated into the caller, and the function's address is never used, then the function's own assembler code is never referenced. In this case, GCC does not actually output assembler code for the function, unless you specify the option `-fkeep-inline-functions'. Some calls cannot be integrated for various reasons (in particular, calls that precede the function's definition cannot be integrated, and neither can recursive calls within the definition). If there is a nonintegrated call, then the function is compiled to assembler code as usual. The function must also be compiled as usual if the program refers to its address, because that can't be inlined.
第 17-39 行是 lcase 展開後的內容,這表示 GCC 啟用最佳化選項時,才會展開 inline function 。由於同時搭配 static 關鍵字,在沒有需要時, GCC 不會產生 assembler code ,所以在此看不到 lcase 的 assembler code (In this case, GCC does not actually output assembler code for the function)。
case_u_1b.asm
儘管啟用了最佳化選項,但此例是透過函數指標 (pointer of function) 調用 ucase ,所以第 28-55 行中, GCC 依然產生了 ucase 的 assembler code (The function must also be compiled as usual if the program refers to its address, because that can't be inlined.)。 GCC 仍然會在可以展開之處展開 inline function ,但在不能展開之處,則用 call 調用。在第 21 行中,便是用 call 調用 ucase 。可以注意到,第 21 行並不是透過原先指定的變數,而是直接取用 ucase 的 address ,這是因為在最佳化情形下, GCC 判斷可以直接取用 ucase 的 address 。
Combination of inline and extern
If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.
This combination of inline and extern has almost the effect of a macro.
When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.
你好, 我最近在學要如何從 C 程式 (main)呼叫 組合語言 程式(function),不知道你是否可以介紹我ㄧ些書或只是網站的教學
主要是因為 DSP或 PICO等,必須使用它的指令來撰寫,有些還有特定的暫存器,所以想要知道如何以 C 來呼叫 DSP或PICO的組合語言程式
Best Regards, Matthew
未留名 (#comment-3407062)
Tue, 24 Oct 2006 14:42:59 +0800
我當年 (大約十年以前) 曾在 80x86 CPU 和 DOS 環境下,用 Microsoft MASM 開發給 QuickBASIC 和 Turbo C 調用的 function library 。記得關於混合語言的使用方法 (BASIC, C, 組合語言互相呼叫彼此的 functuions) ,大約十幾年前還有蠻多資料可參考的。但那早在 Internet 興起前,如今想在網路上找到這類資料,並不容易。自己跑一趟學校的圖書館還快些。
樂多舊回應