將空指標傳遞給 printf 轉換

printf%s 轉換表明相應的引數是指向字元型別陣列的初始元素的指標。空指標不指向任何字元型別陣列的初始元素,因此未定義以下行為:

char *foo = NULL;
printf("%s", foo); /* undefined behavior */

但是,未定義的行為並不總是意味著程式崩潰 - 某些系統採取措施來避免在取消引用空指標時通常發生的崩潰。例如,已知 Glibc 可以列印

(null)

對於上面的程式碼。但是,在格式字串中新增(僅)換行符會導致崩潰:

char *foo = 0;
printf("%s\n", foo); /* undefined behavior */

在這種情況下,它發生是因為 GCC 有一個優化,將 printf("%s\n", argument); 轉換為使用 puts(argument) 呼叫 puts,而 Glibc 中的 puts 不處理空指標。所有這些行為都符合標準。

請注意,空指標空字串不同。因此,以下內容有效且沒有未定義的行為。它只會列印一個換行符

char *foo = "";
printf("%s\n", foo);