[問題] pointer void * a = (void *) i;

看板C_and_CPP (C/C++)作者 (澎湖.仙人掌.234)時間16年前 (2009/03/31 12:25), 編輯推噓25(25041)
留言66則, 7人參與, 最新討論串1/1
請教一個 Pointer的情況 有兩個變數是這樣宣告的 void *arg; int i = 10; arg = (void *) i; 不懂的是 為而arg在assign時是這樣做呢 而不是這樣 arg = &i; 麻煩各位幫我解惑 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.105.238

03/31 12:33, , 1F
原因是void *能指向任何東西嘛?
03/31 12:33, 1F

03/31 12:34, , 2F
可是我有個疑惑 我照你這樣寫 會出現警告
03/31 12:34, 2F

03/31 12:34, , 3F
warning C4312: '型別轉換' : 將 'int' 轉換為較大的'void *
03/31 12:34, 3F

03/31 12:34, , 4F
不是應該一樣size都是4嗎????
03/31 12:34, 4F

03/31 12:34, , 5F
應該是要 arg = (void *) &i; 才對
03/31 12:34, 5F

03/31 12:35, , 6F
照他這樣寫要用的時候 直接cast成 int就可以了
03/31 12:35, 6F

03/31 12:35, , 7F
不會有警告~ 兩邊都是 void* 語法合法
03/31 12:35, 7F

03/31 12:37, , 8F
喔我是說他這種寫法
03/31 12:37, 8F

03/31 12:38, , 9F
它應該要練習用 void*
03/31 12:38, 9F

03/31 12:40, , 10F
這樣寫也可以過 難道是void*無敵嗎? 為啥會有警告說大小不合
03/31 12:40, 10F

03/31 12:43, , 11F
arg = (void *) i; 這語法沒錯~ 但用錯 把這樣是把 10
03/31 12:43, 11F

03/31 12:44, , 12F
當作位址給 arg ... 10 這位址根本不合法
03/31 12:44, 12F

03/31 12:59, , 13F
arg = (void*)&i 和 (void*)i 都合法, 只是結果不同....
03/31 12:59, 13F

03/31 13:00, , 14F
10這個位址不合法沒錯, 不過偶爾好像也會見到這種用cast
03/31 13:00, 14F

03/31 13:01, , 15F
來做某寫特別的passing/處理的樣子@_@"
03/31 13:01, 15F

03/31 13:03, , 16F
順便回2F, 用DevC++ 4.9.9.2測好像不會有warning....
03/31 13:03, 16F

03/31 13:04, , 17F
話說回來, 小轉大應該OK, 大轉小通常才可能有問題不是??
03/31 13:04, 17F

03/31 13:06, , 18F
這邊沒size 問題~ 這邊都是4byte
03/31 13:06, 18F

03/31 13:08, , 19F
在32 bits環境應該是都OK; 不過小弟是說2F說的warning
03/31 13:08, 19F

03/31 13:09, , 20F
假如真的不match, 小轉大應該也不會是什麼問題啊@_@"
03/31 13:09, 20F

03/31 13:30, , 21F
可是他們不是同樣大小嘛?
03/31 13:30, 21F

03/31 13:34, , 22F
我這邊測出來是, 所以您的結果是挺奇怪的:)
03/31 13:34, 22F

03/31 13:35, , 23F
剛刻意測一個char c=10; void *p=(void*)c;
03/31 13:35, 23F

03/31 13:35, , 24F
這個例子DevCpp就會報warning: difference size了@_@"
03/31 13:35, 24F

03/31 13:36, , 25F
所以Q大您真要查, 就sizeof()查一下兩個變數吧....XD
03/31 13:36, 25F

03/31 13:45, , 26F
char c=10; void *p=(void*)c; // 這樣會出現警告是正常的
03/31 13:45, 26F

03/31 13:46, , 27F
(void*)c; 又不是把 c 真的把 變成 4byte
03/31 13:46, 27F

03/31 13:49, , 28F
void *p=(void*)&c; 改成這樣就OK
03/31 13:49, 28F

03/31 13:52, , 29F
應該是說 指標型態轉型只可以用在 address , c 是整數型態
03/31 13:52, 29F

03/31 13:55, , 30F
我懂y大您的意思, 不過我現在就是沒有要取address....
03/31 13:55, 30F

03/31 13:56, , 31F
現在就是純粹刻意要把一個數cast成address來用....
03/31 13:56, 31F

03/31 13:56, , 32F
對~ (void*) (int*) etc 指標這種轉換必須用在address
03/31 13:56, 32F

03/31 13:56, , 33F
用char轉只是要做出Q大遇到的warning問一下size的問題.
03/31 13:56, 33F

03/31 13:56, , 34F
&c 才是address of ... c 是整數
03/31 13:56, 34F

03/31 13:57, , 35F
我印象中我以前在書上看過~ 不過我忘記在哪本書看過
03/31 13:57, 35F

03/31 13:57, , 36F
所以char是刻意搞的特例; 但是int->void*這種case不是沒
03/31 13:57, 36F

03/31 13:57, , 37F
有, 有可能design上int本來的值就是個address, 這樣做的
03/31 13:57, 37F

03/31 13:58, , 38F
好壞先不論, 但是的確有這種int值存address的作法....
03/31 13:58, 38F

03/31 13:58, , 39F
void *p=(void*)(int)c; 你改這樣編譯你就知道
03/31 13:58, 39F

03/31 14:00, , 40F
這樣阿~
03/31 14:00, 40F

03/31 14:01, , 41F
widening coercion理論上的確不該出warning
03/31 14:01, 41F

03/31 14:04, , 42F
用VC2005試int i=10; void *p=(void*)i; 的個case....
03/31 14:04, 42F

03/31 14:06, , 43F
真的有 convert "int to void*" of greater size的warn
03/31 14:06, 43F

03/31 14:06, , 44F
不過對int和void* sizeof都是4, 是小弟我英文不好嗎Orz
03/31 14:06, 44F

03/31 14:07, , 45F
話說上面那段修正一下, 通常會用unsigned的而非signed:)
03/31 14:07, 45F

03/31 14:11, , 46F
我覺得這邊譯器有差異~ 可能要查ANSI ..
03/31 14:11, 46F

03/31 14:11, , 47F
補充, VC2005試char c=10; void *p=(void*)c; 的case.
03/31 14:11, 47F

03/31 14:12, , 48F
竟然完全沒有warning, 我開始懷疑是MS自己在耍寶....Orz
03/31 14:12, 48F

03/31 14:12, , 49F
照y大的加(void*)(int)c; DevCpp沒warn, VC2005有warn.
03/31 14:12, 49F

03/31 14:13, , 50F
其實這種情況很多~ 滿多小地方ANSI 也沒定義~編譯器實作
03/31 14:13, 50F

03/31 14:13, , 51F
上就有差異
03/31 14:13, 51F

03/31 14:13, , 52F
就像y大說的, 看來compiler有差, 那留給強者查吧....XD
03/31 14:13, 52F

03/31 14:14, , 53F
語意問題罷了 其實想怎麼寫都可以 知道自己在幹嘛就好
03/31 14:14, 53F

03/31 14:15, , 54F
的確是語意問題, 只是有時候這種warning可能會造成
03/31 14:15, 54F

03/31 14:16, , 55F
prefast build過不了吧? 如果是compiler問題就滿鳥的Orz
03/31 14:16, 55F

03/31 14:55, , 56F
....上面是吵起來了嗎...
03/31 14:55, 56F

03/31 14:57, , 57F
其實這只是存取特定記憶體位址的值罷了 嵌入式常用到
03/31 14:57, 57F

03/31 19:53, , 58F
沒有吵啊 只是討論熱烈
03/31 19:53, 58F

03/31 19:54, , 59F
MSVS你可以試試看,你用unsigned long long 轉void*反而沒有
03/31 19:54, 59F

03/31 19:54, , 60F
但事實上sizeof(void*)卻又是4 byte 所以有可能是.......
03/31 19:54, 60F

03/31 19:55, , 61F
可能是64位元可攜性警告吧,把它關掉看看
03/31 19:55, 61F

03/31 21:52, , 62F
謝樓上:) 話說MSVS有些warn真的滿煩的, 還有一個常見的
03/31 21:52, 62F

03/31 21:53, , 63F
就是str###()和str###_s(), 上次差點不小心把func換掉.
03/31 21:53, 63F

03/31 21:54, , 64F
幸好主管提醒, 不然掛掉OS build的話小弟就要被定了Orz
03/31 21:54, 64F

03/31 21:55, , 65F
掛掉其他OS的build, 漏字; 本來想用#define / #if來弄.
03/31 21:55, 65F

03/31 21:56, , 66F
偏偏就是有地方用到要回傳char*的, 好像是strstr吧@_@"
03/31 21:56, 66F
文章代碼(AID): #19qPi-pF (C_and_CPP)
文章代碼(AID): #19qPi-pF (C_and_CPP)