我最近重新開始使用C,我決定編寫一個庫作爲stdio.h的包裝。目標是儘可能地執行錯誤檢查,以便用戶在調用stdio函數時不必自行執行。這部分用於學習,部分用於實際使用(因爲我經常使用stdio)。使用可變參數在我的printf包裝中沒有返回錯誤
當我編寫以下內容(在main中)時,gcc在編譯時給出一個錯誤,因爲應該有一個整數作爲另一個參數,但沒有傳遞。
printf("Your integer: %d\n");
在情況下,它是非常有用的,這裏是我的編譯器標誌:
-std=c11 -pedantic-errors -Wall -Wextra -Werror
這是我目前的包裝功能的一部分。它完美和不少錯誤檢查時,通過有效/正確的參數:
uintmax_t gsh_printf(const char *format, ...)
{
va_list arg;
int cnt;
va_start(arg, format);
cnt = vprintf(format, arg);
va_end(arg);
// Analyze cnt and check for stream errors here
return (uintmax_t)cnt;
}
但這裏的問題,如果我叫:
gsh_printf("Your integer: %d\n");
它確實不給出一個錯誤,並且它甚至運行!通常的輸出是一樣的東西:
Your integer: 1799713
或者其他一些數字,這意味着它的訪問沒有分配給它的內存,但它從來沒有給分段錯誤要麼。
那麼,它爲什麼不給出任何類型的錯誤?我該如何編寫自己的代碼,以便在檢查類型,參數數量等後發生編譯時錯誤或至少運行時錯誤?
當然,任何幫助非常感謝,如果您需要更多信息,請讓我知道。謝謝!
看看那裏的printf定義頁眉,它必須有某種註解所以編譯器知道把它作爲格式字符串 – paulm
我以前檢查過,但stdio.h中沒有提示,只是一個合理的正常函數聲明。我找不到一個stdio.c文件,所以我認爲它可能已經用另一種語言編寫或者預編譯或者其他東西。 – Leonhart231
在不添加額外參數的情況下傳遞printf()一個「%d」(因爲printf()使用C的可變參數)在語法上是合法的。編譯器抱怨的原因是因爲它被編程。它盡最大努力注意到這可能是一個「永遠」無法預期的語義問題,因此會引發警告/錯誤。正在顯示的數據是「垃圾」。它不拋出分段錯誤的原因可能是因爲它將先前的堆棧值解釋爲缺少的int參數。除非您瀏覽頁面或其他操作系統錯誤,否則您可能不會看到錯誤。 – MrHappyAsthma