→ Feis: &b 存在且合法. b 不佔空間的話, 試解釋 sizeof(b) 05/12 21:54
&b 當然存在且合法。不存在的是 &b 的地址。
請您再仔細地看上文「&b 的地址(即&&b)並不存在,而且對編譯器來說是非法」
根據 ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
§6.5.3.4
3. ... When applied to an operand that has array type,
the result is the total number of bytes in the array.
這項目特別被舉出來是為了避免 sizeof(b) 中的 b 被 implicitly convert.
所以說,sizeof(b) 仍然是 int b[2] 這個陣列的位元組大小。
→ Feis: b 是個陣列. 但是不占空間嗎? 蠻有趣的 05/12 22:43
b 是陣列名稱, b[] 才是是陣列,該陣列的型態是 int[2]。
b 不佔空間,只有 b[] 佔空間,但是實作上需要使用一個空間來儲存 b[2] 的地址。
而且這個空間也一樣是放在 stack 中,會隨函式的增長或消滅來生成與毀滅。
推 CaptainH: b 是 lvalue 05/12 22:53
推 AstralBrain: b[2]不是陣列, b[2]是陣列的第3個element 05/12 22:57
已修正,感謝提出錯誤。
這是邏輯謬誤,使用C++來檢視C?
在C語言中,不實際擁有在記憶體中一塊物理位置的稱之為右值。
b 是陣列名稱(並非陣列本身),當然在記憶體中不擁有物理位置。
推 CaptainH: 那你怎麼解釋An lvalue or rvalue of type "array of N 05/12 22:58
→ CaptainH: T"這個東西? 05/12 22:58
→ Feis: 放在 stack 中? 這也蠻有趣的 05/12 23:15
推 CaptainH: 修正後仍是錯,b[]不是正確的語法,更別說他代表什麼了 05/12 23:15
不然大大覺得應該要如何準確地表示陣列?
陣列一語本來就不是正確的語法,最正確的用法是:
It has type `int[2]`.
推 Feis: 推一下右值的定義. 蠻有趣的 05/12 23:17
L-values have storage addresses that are programmatically accessible to the
running program, meaning that they are variables or dereferenced references to
a certain memory location.
Does b have its own storage address? Only b[0] and b[1] does!
→ Feis: 對了. 忘了問 4.2.1 的那節是 ISO C 哪個版本? 05/12 23:21
→ Feis: 我建議你可以去 C 標準找一下 rvalue (如果你在說 C 的話) 05/12 23:22
→ Feis: 所以你的 compiler 印不出 &b ? 05/12 23:24
`b` has type `int[2]`, and `&b` has type `int(*)[2]`.
Type `int(*)[2]` will decay to `int*` while the array length is useless.
→ Feis: 此外你可以想想 struct 變數~ 比對一下跟 array 的差別 05/12 23:26
→ Feis: 還有你的 sizeof 的說明不是已經說了 b 是 array type ? 05/12 23:27
→ Feis: 如果 b 不是 array type, 那 sizeof(b) 到底是甚麼.. 頭痛 05/12 23:27
我承認我真的不知道 b 是不是 array type,
但是 b 肯定是 int[2],只是在程式碼中會被轉型成 int(*)[2]。
→ Feis: b 會被轉成 &b[0] 喔~ 所以是 int * 而不是 int(*)[2] 05/12 23:41
絕不是 int*
http://stackoverflow.com/questions/2893911/
address-of-an-array-address-of-being-ignored-be-gcc
int(*)[2] 會 decay 成 int* 當陣列長度無用的時候,
→ Feis: 恩.. 我們看的是同一篇嗎 XDDDDD 05/12 23:45
→ Feis: 我需要一點時間理解. 晚安 : ) 05/12 23:46
A pointer that points to an array of 50 ints has type int (*)[50] - that's
the type of &test.
→ Feis: 是阿. 那不就是 &b 嗎 xD 05/12 23:48
是呀~所以 &b has type `int(*)[2]` not type `int*`.
→ Feis: 但是你說的不是 b 在程式碼中會被轉 int (*)[2] 嗎? 05/12 23:49
→ Feis: 我說的是 b 會轉為 int * 不是 &b 阿 QQ 05/12 23:50
喔喔喔~我錯亂惹~
整理一下:
b: int[2] -> int* (implicit conversion: array-to-pointer conversion)
&b: int(*)[2] (address-of operator)
→ Feis: 用編輯文章好難回阿 xD 原文 &b 的 address 應該不是 &&b 的 05/12 23:57
→ Feis: 意思. 或者我以為他不是 xD 05/12 23:58
搞不好真的不是,中文有時候會怪怪der.
→ bibo9901: 你是跟葉孤紅一樣有人專門寫一本錯誤的書給你看嗎 XD 05/13 00:00
XDDD
錯亂惹啦~先去準備偏微分啦!!!
這篇的重點是:
1. Implicit type conversion: array-to-pointer conversion
2. b has type int[2], and &b has type int(*)[], and &&b is invalid.
→ bibo9901: 既然 b 是一個 rvalue 那你怎麼能用 address-of 呢? 05/13 00:03
暈~
b 在 code 中被轉換的才是 rvalue,
在 sizeof operator 中不用被轉換,是 lvalue!!!
→ Feis: 提醒一下... standard conversion 是 C++ 的... 05/13 00:06
喔喔喔~是 Implicit type conversion
改了改了
→ bibo9901: 我說的是 address-of "&" 不是 sizeof 05/13 00:10
眼殘XD
compiler 很聰明吧~
也許看到前方有&就不會作 implicit conversion 吧?阿災?
→ bibo9901: 如果 b 不佔空間的 rvalue, 那你寫下 &b 就是非法的 05/13 00:11
→ Feis: 其實我不知道 rvalue 不占空間這樣的說法到底該怎麼解釋 xD 05/13 00:12
→ Feis: 我是覺得 rvalue 很玄阿~ 大家晚安~ 05/13 00:14
→ bibo9901: 的確很怪, 但暫且假設如他所說的那樣, 對 b 取址更怪 05/13 00:14
我翻遍標準文檔就還是覺得怪怪的
可能就真的不隱式轉換了吧~
※ 編輯: Hazukashiine (140.113.91.124), 05/13/2015 00:18:09
→ Feis: 對轉換有興趣請參閱 C89 標準 3.2.2.1 05/13 00:25
→ yvb: 94行說 "使用C++來檢視C?" 05/13 14:57
→ yvb: 但 35行 "ISO 文件 §4.2.1" 似乎引自 C++ ?? 05/13 14:57
→ yvb: 另外, 原原PO問 "為什麼 b 跟 &b 兩個address會一樣" 05/13 15:02
→ yvb: 然後 30行那邊回 "b 跟 &b 的地址不一樣" ... 05/13 15:02
→ yvb: 感覺答非所問? 還是 "地址不一樣" 似乎不是唯一解?? 05/13 15:03
→ yvb: 上面 F大的 3.2.2.1 其實是指 6.3.2.1 ? 05/13 17:09
→ Feis: yvb: 好像是版本差異 XD 那是 C89 Draft 05/13 17:20
→ yvb: soga... C89 3.2.2.1 => C90 6.2.2.1 => C99~C11 6.3.2.1 05/13 17:57
→ yvb: c89 要 google ansi.c.txt 才找得到 :P (好像沒 pdf 的?) 05/13 17:59