Re: [問題] 字元指標的問題

作者: poyenc (髮箍)   2019-09-06 23:11:04
這裡給的錯誤訊息不明確, 推文中提到的型別檢查變嚴格也不是原
因. 在講原因前先來瞭解賦値/初始化敘述最重要的幾個要素:
B = A;
當我們要把 A 賦値給 B 的時候, 至少需要弄清楚以下 3 點:
1. A 的型別為何?
2. B 的型別為何?
3. 可不可以透過隱式轉換 (implicit conversion) 將
A 的型別轉換到B 的型別?
簡單舉個例子, 我們都知道以下的程式碼是合法的:
int i = 0;
int* pi = &i; // 1. pi's type is int*
void* pv = pi; // 2. pv's type is void*
// 3. valid, convert int* to void*
再回到原本的問題:
char* str = "hello";
在將 string literal 給 char* 物件做初始化之前, 你需要知道它
的型別是什麼, 據我所知在 C 和 C++ 內定義的型別不同:
C (n2346) https://bit.ly/2lHYvLe
6.4.5.6
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.
C++ (n4830) https://bit.ly/2k3F5jL
5.13.5.6
An ordinary string literal has type “array of n const
char” where n is the size of the string as defined
below, has static storage duration, and is initialized
with the given characters.
所以你的程式碼效果其實和下面的差不多 (C++):
const char literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
char* str = literal;
會有錯誤的原因在這:
透過隱式轉換無法將指標的 constness 給移除.
還有另外一個地方需要注意: 因為 string literal 本身是陣列,
陣列賦値/計算之前會先退化 (decay) 成指標 (也是轉型的一種),
錯誤訊息省略描述這個步驟所以很容易讓人誤解它的型別. 最後總
結一下編譯器做的事情:
1. 取得 "hello" 的型別, 為 const char[6]
2. 因為要賦値, 把 "hello" 陣列退化成 const char*
3. 取得 str 的型別, 為 char*
4. 檢查能否透過隱式轉換將 const char* 轉成 char* (失敗)
第一個步驟 C 和 C++ 編譯器取得的型別相異, 導致結果也不同,
這也是常常拿網路上的原始碼會編不過的原因, 其實 C 和 C++ 是
兩個 (只有) 語法相似但本質不同的語言.
作者: kaneson (Lance)   2019-09-07 09:42:00
小弟認為隱轉跟字串常數的建立是兩回事的, 因為用顯轉就可解決。原po的問題我過去的記憶不曾遇到, 加上小弟最近在寫c#(碰到不給隱轉成parent class), 所以認為vs是朝向strong type checking一派的。而且原po的code來源因使用iostream所以應為c++,(用.c丟給gcc/g++不給過) ,再來字串常數的隱轉問題用gcc與g++及使用c++17都只有warning, 所以我覺得問題只是微軟走嚴格趨勢
作者: loveme00835 (髮箍)   2019-09-07 12:18:00
樓上怎麼會有因為「只有 warning」所以程式碼「不是ill-formed」的結論?
作者: kaneson (Lance)   2019-09-07 17:47:00
因為只是要回答原po問的教學文章貼上卻會報錯的問題出在編譯器差別不是語法或c/c++的差別。code本質對錯就看此篇樓主就行了
作者: james732 (好人超)   2019-09-07 22:21:00
感謝回答

Links booklink

Contact Us: admin [ a t ] ucptt.com