1. 程式人生 > >warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

最近複習到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的指標當然會出錯了
  • 最後第三種寫法是編譯執行通過了