2011-11-23 71 views
4

可能重複:
Are string literals const?ANSI C:指向字符串字面量

是在ANSI C以下有效?

#include <stdio.h> 

/* This returns "Hans" if arg != 0, "Gretel" if arg == 0 */ 
char* foo(int arg) 
{ 
    return arg ? "Hans" : "Gretel"; 
} 

int main() 
{ 
    char* p_ch; 

    p_ch = foo(1); 
    printf("%s\n", p_ch); 
    p_ch = foo(0); 
    printf("%s\n", p_ch); 

    return 0; 
} 

代碼在GCC/Linux下編譯並運行良好。

的MinGW/Windows的說:

invalid conversion from `const char*' to `char*' 

微軟的Visual C/C++ 2008是細跟的代碼。

  1. 我可以將char*變量分配給字符串,而不是在其初始化點嗎?
  2. 我讀過字符串文字有static定位類。這是否意味着它們在它們所定義的功能之外是不可見的?
  3. 自從const類型轉換爲非const類型時,它們是無效的嗎?
+0

我會聲明'foo'返回'const char *'。當編譯爲C++時,代碼變得無效。我不夠標準的專家來解釋爲什麼......我會希望GCC給出一些警告(但是即使是使用'-Wall -Wextra'的gcc 4.6也沒有)。 –

+0

@Basile,因爲gcc正在編譯C代碼。在C中有這個_nothing_錯誤。如果你用g ++編譯它,那將是另一回事,但顯然如果你嘗試編譯完全有效的C代碼,gcc並不認爲它是一個問題。像「不能使用變量名'new''''''''''''''''''''''''''''可能有一天需要使用C++編譯器編譯這個''會令人討厭:-) – paxdiablo

+1

@BasileStarynkevitch:gcc -Wwrite-警告。這可能不是'-Wextra'的一部分,因爲C庫的某些部分可能依賴於此功能;例如'strerror'具有返回類型'char *',但可以使用字符串文字數組來實現。 –

回答

5

是的,這是有效的標準C.但是,它只是有效的,因爲字符串文字具有類型char[]向後兼容;爲了安全起見,您應該確保從foo a const char*的返回值。寫入由foo返回的任一字符串都會引發未定義的行爲。

如果您的編譯器對此抱怨,那麼您可能意外地使用了C++編譯器。在C++中,字符串文字的類型爲const char []。 (如果你改變char*const char*,你的程序奇蹟般地成爲一個有效的C++程序也是如此。)

我可以將char*變量分配給一個字符串以外的其他地方,在它的初始點?

你的意思是

char *p; 
// do some other stuff 
p = "literal"; 

?是的,這是可能的。

我讀過字符串文字有靜態分配類。這是否意味着它們在它們所定義的功能之外是不可見的?

你混淆了靜態分配和static變量。您當然可以在另一個翻譯單元中使用foo的結果。

從什麼時候開始,從常量類型到非常量類型的轉換無效?

自1989年起正式將const引入C.您必須明確地將const關閉。

1

您從MinGW/Windows編譯器獲得的錯誤消息強烈建議您將此代碼編譯爲C++。在C語言中,字符串文字有char[N]類型(與C++中的const char[N]相反)。在C語言中,你不應該得到這個錯誤信息。儘管如此,即使在C字符串中文字也是不可修改的,這意味着當指向字符串文字時堅持const char *指針是一個好主意。

您的問題編號1有點奇怪。字符串文字是無名稱對象,這意味着初始化是直接將指針指向字符串文字的唯一方法。沒有別的辦法。稍後,您可以將您的非常量指針複製到其他非常量指針,這是正確的。請記住,您不允許通過這些指針將任何東西寫入字符串文字中:字符串文字是不可修改的。

你的問題2也沒有多大意義。 「可見性」是名稱的財產。字符串文字是無名稱對象。它們在任何地方都不可見。他們不可見,因爲他們沒有名字。由於他們沒有名字,所以「抓住」一個字符串文字並保持它的唯一方法是在指針初始化時附加一個指向它的指針(如你的例子)。可見度與它無關。字符串文字確實具有靜態存儲持續時間,這意味着它們「永遠活着」:它們只要程序運行就存在。在您的示例中,即使在foo退出後,字符串文字"Hans""Gretel"也會繼續存在,這意味着由foo返回的指針保持有效。

您的問題3的答案是:從C語言中從不存在的const指針到它們的非常量對應的隱式轉換,即它始終是無效的。您必須使用顯式強制轉換才能執行此類轉換。