在學習共享行程信號量時,我注意到 sem_open() 具有兩個函式原型:https ://man7.org/linux/man-pages/man3/sem_open.3.html
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
如果 C 不支持函式多載,這怎么可能?
uj5u.com熱心網友回復:
C沒有多載。它確實具有可變引數功能。
多載函式是具有多種形式的函式的函式,每種形式都有不同的引數。
可變引數函式是 C 語言中可以接受可變數量引數的函式。這用省略號 (...) 表示,雖然這在手冊頁中不明顯,但如果您查看 sem_open() 的源代碼,您可以看到它:
/* Open a named semaphore NAME with open flags OFLAG. */
extern sem_t *sem_open (const char *__name, int __oflag, ...) __THROW;
如您所見,在 __name 和 __oflag 之后,省略號表示技術上可以輸入任意數量的引數。但是手冊頁指出的是 sem_open() 可以實際處理的變數。所以真的,這不是兩個具有不同邏輯的函式,而是一個可以處理兩組不同引數的函式。
如果您想了解更多資訊,請參閱這篇有趣的文章,其中介紹了可變引數函式背后的一些歷史。
uj5u.com熱心網友回復:
密鑰位于手冊頁(您鏈接的)中:
如果
O_CREAT
在 中指定oflag
,則必須提供兩個附加引數。
這正是 C 中可變引數函式的作業方式。可變引數函式具有固定數量的引數,每個引數都有一個明確定義的型別,然后是 a ...
,它可以是任何型別的任意數量的引數,但前提是被呼叫的函式必須能夠找出每個引數的型別才能參考它。printf
確實是最明顯的例子:格式字串包含足夠的資訊,printf
可以準確地知道期望的引數數量和型別。
請注意,不允許猜測。如果函式請求一個未提供的引數或請求與提供的引數不同的型別,它不會得到友好的錯誤指示或第二次機會。結果是未定義的行為:任何事情都可能發生,包括突然終止或無意義的結果。或者一個看似有道理但在現實中沒有根據的結果。
Like open
,sem_open
使用它來允許僅在某些明確定義的情況下需要的引數。如果呼叫可能會創建一個新的信號量(或檔案,在 的情況下open
),它將請求附加引數,假設它們是檔案中指定的型別。
呼叫者負責確保呼叫正確。請注意,由于可變引數沒有宣告的型別,編譯器無法插入型別轉換。因此,如果函式需要 a double
,則不能使用 a 呼叫它int
,這通常是可能的。此外,如果一個可變引數應該是void*
,它必須是void*
,而不是,例如,0
(或NULL
),因為無法完成從 0 到空指標的自動轉換。
但是,允許呼叫者提供太多引數,或者相反,被呼叫函式不需要檢查提供的每個引數。(它不能跳過引數,但它不需要到達串列的末尾。)
回想起來,這似乎是一個糟糕的語言特性。但當時這似乎是一個好主意,而且現在不會消失。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/436287.html