restrict
Origin: from C99 - Wiki #Design
restrict qualification allows more aggressive code optimization, removing compile-time array access advantages previously held by FORTRAN over ANSI C[7]
Definition:
Reference my study on the 6.7.3.1 Formal definition of
restrict
for detail.
restrict
qualifier requires that the pointers do not reference overlapping objects. If the objects referenced by arguments to functions overlap (meaning the objects share some common memory addresses), the behavior is undefined. (See also undefined behavior 68.)
Extensive reading: 真的理解 C 語言的 types 嗎?
by Jserv
static
reference 6.2.2 Linkage of identifiers
and the implication of
static
is mentioned on ¶3
inline
introduced in 6.7.4 in C99 and my study note on the section
From 〈C語言入門與進階教學〉- 鄭昌杰老師
初始版本的程式碼為:
bbsort_itr.c
欲改進的函式bbsort()
, 擷取程式碼如下:
9.3 巨集
改寫如下,原始碼請參考bbosrt_macro.c:
使用巨集雖然可以達到我們減少函式呼叫的成本的目標,但設計巨集要非常小心,它很容易帶來許多誤動作以及語法結構上的錯誤。… 由於巨集是直接將內容取代於程式碼,您必須確保取代後的結果不會影響前後文的語法、運算邏輯與副作用(side effect)。
例如把SWAP
裡的大括號去掉:
編譯時,加上
ERR_INJ_INGNORING_BRACKETS
這個定義。在GCC, 利用-D name
, 可參考3.13 Options Controlling the Preprocessor對應命令為:
gcc -o bbsort_macro.o -c -D ERR_INJ_INGNORING_BRACKETS bbsort_macro.c
會有編譯上的錯誤,A[j]=t用了未宣告的變數t;完整的訊息如下:
把true
定義為零
另外,編譯器不會檢查巨集定義的邏輯正確性,您有可能會不小心把某個"名詞"定義成錯誤的意義。如下:
承上gcc的命令,只須將GCC選項中的定義改成
ERR_INJ_SETTING_TRUE_0
對應命令為:
gcc -o bbsort_macro -D ERR_INJ_SETTING_TRUE_0 bbsort_macro.c
true
定義帶入bbsort
中比較相連的兩個陣列元素的判斷。程式修改的部份如下:
–> 可以觀察到這種巨集會造成所有邏輯都反過來了!
於是bbsort並不會將陣列由小排大,而是由大排到小。加上error injection前跟後的結果如下:
這並沒有一個很好的方法,
但若巨集內容是一個運算式且回傳值就是該運算式的結果,那麼這個巨集就很像是一個有回傳值的函式。請看這個例子:
此例中的
MIN
其實只是代表一個條件運算式
如果巨集內容不是只有一個運算式,且回傳值是巨集裡的某個區域變數;C99沒有定義此語法,但GCC有提供一個敘述運算式(statement expression)來解決這個問題。
若有數個敘述句,先以大括號包起後,再以小括號包住,那麼就會變成一個運算式,運算結果為最後一個敘述句的運算結果。請看下面這個例子:
9.4 行內函式
提供「減少呼叫函式的次數來降低成本」的另一個方法;如上節所述,稍不小心就會設計出隱藏錯誤的巨集。
inline是C99的一種特別的關鍵字,以inline所宣告的函式稱為行內函式(inline function),編譯器會將行內函式之定義內崁在呼叫的程式碼中,就好像巨集般的不需要呼叫成本。
更重要的是,行內函式能夠被檢查出編譯階段的錯誤。
因為是置換原來宣告的function。
設計行內函式有一個很重要的要求,
很明確地告訴編譯器行內函式的連結方式(6.2.2 linkages of identifiers)。換句話說,您必須清楚地指示行內函式是內部連結還是外部連結;必須從下列兩種方式擇一宣告:
呼應 C99 於 §6.7.4 Function specifier ¶6的定義
Any function with internal linkage can be an inline function.
若該function的identifier是file scope, 且包含static storage-class specifier,則該
identifier
有internal linkage
- defined in [§6.2.2 ¶3]( )
延伸閱讀: external declarationImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
inline是一個「建議」性質的關鍵字,是否能夠真正表現出「行內函式」應有的行為還是的取決於編譯器。
行內函式還有一個重要特性,就是它的可用範圍為一個編譯單元,有三件事您必須注意:
map Any function with internal linkage can be an inline function. ?
An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit.
For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit.
The Compilation Process
in〈EFFETIVE C〉for a function, declartion is it's prototype
the implementation of a function or an object
note on
§1.10 External Variable and Scope
in K&R C
From [A.10 External Declarations] in K&R C
The unit of input provided to the C compiler is called a translation unit; it consists of a sequence of external declarations, which are either declarations or function definitions.
From ISO C99
translation unit, 5.1.1.1, 6.9
參考先前閱讀 chap 5.1.1.1 筆記的結論:
綜合上述兩個註解;translation unit為一個source file, 且包含透過前置處理導引;前置處理器指示將外在宣告(Image Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
External Declaration
),headers和source files包含進來,(? not sure about the correctness of the statment)在程式執行時,再到對應的記憶體位置找對應的指令(利用symbol table)。
Examples from on §9 PREPROCESSOR in 〈EFFECTIVE C〉
¶ The Compilation Process
A preprocessing directive causes the preprocessor to take an action that might alter the resulting translation unit, meaning the code you write is often not the same code consumed by the translator. Compiler implementations usually provide a way to view the preprocessor output, called a translation unit, passed to the translator.
Table 9-1: Outputting a Translation Unit
Compiler | Example command line |
---|---|
Clang | clang other-options -E -o output_file.i source.c |
GCC | gcc other-options -E -o output_file.i source.c |
¶ File Inclusion
A powerful feature of the preprocessor is the ability to insert the contents of one source file into the contents of another source file by using the #include
preprocessing directive.
Table 9-2: Header File Inclusion
Table 9-3: Transitive Header File Inclusion
In computer science, a type punning is any programming technique that subverts or circumvents the type system of a programming language in order to achieve an effect that would be difficult or impossible to achieve within the bounds of the formal language.
pun verb (puns, punning, punned) [no object]
make a joke exploiting the different possible meanings of a word: his first puzzle punned on composers, with answers like “Handel with care” and “Haydn go seek”.
雙關語sub·vert
Undermine the power and authority of (an established system or institution).
顛覆傳統cir·cum·vent
Find a way around (an obstacle).
利用他解,繞過程式語言的限制
In C and C++, constructs such as pointer type conversion and union
C++
adds reference type conversion andreinterpret_cast
to this list — are provided in order to permit many kinds of type punning
1 Sockets example
One classic example of type punning is found in the Berkeley sockets interface.
struct sockaddr_in
is freely convertible to a pointer to struct sockaddr
;
reference: §6.2.5 Type ¶27
imply
interchangeability
of thetype
pointed by a pointer: the same representation and alignment requirements 謝阿Sa
此 section 列出 interchangible 的 types,如下:
void *a
<-> char *a
qualified
or unqualified
versions of compatible types
qualified adj.
not complete or absolute; limited:
e.g., "pointer to const- qualified float
" type descripted in ¶28
pointer to float
type:
stucture
typesunion
typesOften seen in the programming world is the use of "padded" data structures to allow for the storage of different kinds of values in what is effectively the same storage space.
利用
呼應上述提到的interchangibility
;透過共用儲存空間,來降低記憶體的使用量。
Floating-point example
However, supposing that floating-point comparisons are expensive, and also supposing that float is represented according to the IEEE floating-point standard, and integers are 32 bits wide, we could engage in type punning to extract the sign bit of the floating-point number using only integer operations:
…
x
is float
but it is read through an expression of type unsigned int
在記憶體中,資料如何被安排及存取
It consists of three separate but related issues: data alignment, data structure padding, and packing.
Problems
The CPU accesses memory by a single memory word at a time. Aligned accesses will always access a single memory word. This may not be true for misaligned data accesses.
If the highest and lowest bytes in a datum are not within the same memory word the computer must split the datum access into multiple memory accesses.
This requires a lot of complex circuitry to generate the memory accesses and coordinate them. To handle the case where the memory words are in different memory pages
Some processor designs deliberately avoid introducing such complexity, and instead yield alternative behavior in the event of a misaligned memory access.
e.g. implementations of the ARM architecture prior to the ARMv6 ISA require mandatory aligned memory access for all multi-byte load and store instructions.[8]
the result of attempted misaligned access might be to round down the least significant bits of the offending address turning it into an aligned access
Data structure padding
extended reading: 3.9.3 Data Alignment in CSAPP
object, 3.14
region of data storage in the execution environment, the contents of which can represent values
my note onImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
lvalue
C Primary expressionsImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Primary expressions are the building blocks of more complex expressions.
Explaination in zh-tw: 識別字(identifier
)是一個構件;構建塊(building block),提供它的宣告,用來指派一個物件(object
) (在此情況,是一個lvalue
)或是一個function (在此情況,它是一個function designator
)。
RISC-V function
: 3-Acquire-local-storage-resources-needed-for-functionChapter 3: Machine-Level Representation of Programs
ASM:IA32 — IA32 programming