從根本上說,是的,它是安全的,因爲它是靜態的,它的值將無限期地持續下去。
從某種意義上說,您已經返回了一個指向變量數據的常量指針,而不是指向常量數據的變量指針,這並不安全。這是更好,如果調用函數不允許修改數據:
const char *GetString(void)
{
static char sTest[5];
strncpy(sTest, "Test", sizeof(sTest)-1);
sTest[sizeof(sTest)-1] = '\0';
return sTest;
}
在簡單情況下所示,幾乎沒有必要擔心緩衝區溢出,雖然我的代碼版本不擔心,並確保空終止。另一種方法是使用TR24731功能strcpy_s
代替:
const char *GetString(void)
{
static char sTest[5];
strcpy_s(sTest, sizeof(sTest), "Test");
return sTest;
}
更重要的是,這兩個變種返回一個(變量)指針常量數據,因此用戶不應該去修改字符串和(可能)踐踏外陣列的範圍。 (As @strager在註釋中指出,返回const char *
並不保證用戶不會嘗試修改返回的數據,但是他們必須轉換返回的指針,使其不是const,然後修改數據;這會調用未定義的行爲,任何事情都有可能發生。)
字面返回的一個優點是通常可以通過編譯器和操作系統來強制執行不寫的承諾。該字符串將被放置在程序的文本(代碼)段中,並且如果用戶嘗試修改返回值所指向的數據,操作系統將生成一個錯誤(Unix上的分段違例)。
[至少有一個答案指出代碼不可重入;那是對的。返回文字的版本是可重入的。如果重入是很重要的,接口需要被固定,這樣,來電提供了數據存儲的空間]
「一般來說,他們應避免」可能是太強大了,但可以肯定的是你應該意識到風險和限制。爲了澄清_why_其確定的+1。 – dmckee 2009-01-17 18:15:02
我同意dmckee,重入問題是因爲在函數調用中靜態設計是活着的。這不是不好的行爲。但你的確應該知道風險。 – 2009-01-17 18:18:44