warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
阿新 • • 發佈:2018-11-05
最近複習到C++的虛擬函式,想輸出一下虛擬函式表的地址,但是在編譯的時候遇到下面這個錯誤:
my_virtual.cpp: In function ‘int main()’: my_virtual.cpp:29:39: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] int *vtbl_addr=((int *)*(int *)(&b)); //② ^ my_virtual.cpp:33:63: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] printf("第一個虛擬函式地址:%p\n",(void *)*(vtbl_addr)); ^ my_virtual.cpp:34:67: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] printf("第二個虛擬函式地址:%p\n",(void *)*(vtbl_addr + 1)); ^ my_virtual.cpp:37:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] pfun = (Fun)(*vtbl_addr); //vitural f(); ^ my_virtual.cpp:41:34: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] pfun = (Fun)(*(vtbl_addr + 1)); //vitural g(); ^
原始碼如下:
#include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; class Base { public: virtual void f() { cout << "Base::f" << endl; } virtual void g() { cout << "Base::g" << endl; } }; typedef void(*Fun)(void); //函式指標 int main() { Base b; printf("sizeof(int)=%d,sizeof(int *)=%d,sizeof(void *)=%d\n",(int)sizeof(int),(int)sizeof(int *),(int)sizeof(void *)); //int vtbl_addr=((int *)*(int *)(&b)); //① //int *vtbl_addr=((int *)*(int *)(&b)); //② unsigned long int *vtbl_addr=((unsigned long int *)*(unsigned long int *)(&b)); //③ printf("虛表地址:%p\n", (void *)vtbl_addr); printf("第一個虛擬函式地址:%p\n",(void *)*(vtbl_addr)); printf("第二個虛擬函式地址:%p\n",(void *)*(vtbl_addr + 1)); Fun pfun = NULL; pfun = (Fun)(*vtbl_addr); //vitural f(); printf("f() addr:%p\n", (void *)pfun); pfun(); pfun = (Fun)(*(vtbl_addr + 1)); //vitural g(); pfun(); printf("g() addr:%p\n", (void *)pfun); return 0; }
除錯過程:
- 最開始是用的一個int型別去儲存虛擬函式表的地址,在windows下編譯、執行是通過的,但是放在win10的子系統下編譯時碰到了上述警告,提示大小不一樣,才想到64位系統指標的大小是8byte
- 然後寫下了第二句話,用指標儲存地址這總沒錯吧,但是編譯的時候還是碰到了這個警告
- 又試了dynamic_cast來強制轉換,emmm,還是不行,最後看cpp參考手冊的時候看到dereference這個單詞,才想到
(int *)(&b)
是把b
的地址轉化為(int *)
,那麼解引用的時候得到就是一個int
型別,就是說還是4byte,轉化為8byte的指標當然會出錯了 - 最後第三種寫法是編譯執行通過了