# Linux2025q1: Pointer Write-Up ## [signal](https://man7.org/linux/man-pages/man2/signal.2.html) - `sighandler_t` 打開 [Linux manual page - signal(2)](https://man7.org/linux/man-pages/man2/signal.2.html) 可以看到以下定義: ```c #include <signal.h> typedef typeof(void (int)) *sighandler_t; sighandler_t signal(int signum, sighandler_t handler); ``` 其中,我們看到一個非常酷炫的用法 `typeof(void (int))`,這是什麼鬼? 翻閱 C11 規格書第 §6.2.5 Types 有以下描述: >Types are partitioned into object types (types that describe objects) and **function types** (types that describe functions) >A **function type** describes a function with specified return type. A function type is characterized by its return type and the number and types of its parameters. A function type is said to be derived from its return type, and if its return type is T, the function type is sometimes called ‘‘function returning T’’. The construction of a function type from a return type is called ‘‘function type derivation’’. 所以 `void(int)` 實際上是一個函式型態 (function type),與物件型態 (object type) 有別。而 `typeof` 作為 C23 的關鍵字,型態可作為其輸入參數的一種可能,因此 `typeof(void (int))*` 返回是一函式指標型態。 考慮以下寫法: ```c void (int)* sighandler_t; ``` 是否可行呢?答案是 **不行** !! 編譯不會通過。 由於函式型態不是物件型態,是不能作為變數的類型宣告使用的。 如果要的話只能使用這種寫法: ```c typedef void (*sighandler_t)(int); ``` :::info :question:還是不懂, `typeof(void (int))` 本質上不是回傳 `void (int)` 嗎?,為甚麼又可以使用指標了? ::: ## Type names (TODO) 在第 §6.7.7 型態名 (type names) 章節中提到: >In several contexts, it is necessary to specify a type. This is accomplished using a type name, which is syntactically a declaration for a function or an object of that type that omits the identifier. 而 type names 的定義由以下組成: - specifier-qualifier-list - abstract-declarator (可選) Abstract-declarator 又有兩種組成可能: - pointer - pointer (可選) + direct-abstract-declrator :::success **Specifier V.S. Qualifier** - Specifier (說明符): `int`, ..., `typedef`, `struct`, `unsigned` - Qualifier (限定符): `const`, `volatile`, `_Atomic`... ::: 微軟的 **抽象宣告子 (abstract declarator)** [介紹頁面](https://learn.microsoft.com/zh-tw/cpp/c-language/c-abstract-declarators?view=msvc-170)提到: >指標修飾詞 (*) 永遠會位於宣告子的識別項之前 故可以區分以下兩者的差距: ## Function Pointer V.S. Function Designator ```c ```