標籤:

字元串字面值傳入函數時候是用什麼形式?

之前一直認為字元串字面值傳入函數時,是以const char*的指針形式傳入,但是今天無意間發現:

void func (char *);

如果有這樣的函數,需要的是一個char型的指針,我們都知道底層const無法被忽略,也就是無法將const char *傳入,但是如果傳入字元串字面值,編譯器不會發出錯誤,卻只是提出警告:deprecated conversion from string constant to char*

當然,如果是用const char *的指針傳入,會發出錯誤的信息。

如果形參類型換為const char *,就完全沒有問題。

所以我想問,字元串字面值傳入函數時,是怎樣傳進去的?


在 C99 [1] §6.4.5 中

5 ... The multibyte character
sequence is then used to initialize an array of static storage duration and length just
sufficient to contain the sequence. For character string literals, the array elements have
type char
, and are initialized with the individual bytes of the multibyte character
sequence. ...

那麼字元串字面值是靜態數組 char[n],n 為字元串序列的長度。

它以 char* 參數類型傳入函數是可以的,但是:

6 ... If the program attempts to modify such an array, the behavior is
undefined.

修改它的內容是未定義行為。因此一般編譯器會認為轉換為 char* 可能有風險,所以告警。

但在 C++11 [2] §2.14.5 中

8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow
string literal has type 「array of n const char」, where n is the size of the string as defined below, and has
static storage duration

這明確說明字元串字面量是 const char[n] 類型,轉型至 char* 是不合法的。

綜上所述,無論是在 C 或 C++ 中,當字元串參數是只讀的時候,請使用 const char* 作為參數類型。

[1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

[2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf


就是傳的const指針,因為舊的標準曾經允許過字元串字面值轉為char*,很多編譯器也提供把字元串字面量儲存在非常量區的選項,所以新的標準多半沒有error,而是給一個warning

實際上修改字面值還是UB


字元串常量本來就不允許修改。


當你寫一個字元串字面值,這個字元串被存儲到只讀的段中,同時,會有一個對應的地址。傳入的時候傳入的是這個地址。


推薦閱讀:

為什麼C語言在printf內賦值有「不及時」的情況?
如何在C++中拋出一個編譯錯誤?
為什麼C語言沒有String類型?
想開始寫技術博客(c++),應該在CSDN上呢,還是知乎呢?
*a.b()是什麼意思,運算符順序是怎麼看的?

TAG:CC |