2013-08-27 44 views
1

我使用QueryInterface函數,該函數將根據IID返回給定接口上的指針。GCC警告「解引用類型指針會破壞嚴格別名規則」

DecodingFramework::IVariableFramerate* pInt = NULL; 
DecodingFramework::DecodeResult iVFR = pVideoDescription->QueryInterface(IID_IVariableFramerate, (void**)(&pInt)); 
if(pInt != NULL && iVFR == DF_SUCCESS) 
{ 
    //use the IVariableFramerate interface using pInt 
} 

但在該代碼(void**)(&pInt)產生與消息的錯誤dereferencing type-punned pointer will break strict-aliasing rules

我的代碼更新到以下幾點:

void* pInt = NULL; 
DecodingFramework::DecodeResult iVFR = pVideoDescription->QueryInterface(IID_IVariableFramerate, &pInt); 
if(pInt != NULL && iVFR == DF_SUCCESS) 
{ 
    DecodingFramework::IVariableFramerate* pVideoVFR = reinterpret_cast<DecodingFramework::IVariableFramerate*>(pInt); 

    //use the IVariableFramerate interface using pVideoVFR 
} 

我發現很多相關的警告信息,但問題主要是當投射更復雜的數據,而不僅僅是地址指針到void**? 真的有問題嗎?我不明白這個警告背後的理由。

+2

可能有幫助,關於嚴格別名的好文章[Type-punning and strict-aliasing](http://blog.qt.digia.com/blog/2011/06/10/type-punning-and-strict ),這是一個更詳細的內容,但要消化[理解嚴格別名](http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html)需要更長的時間。 –

+2

您是否閱讀過其他許多問題(和答案),標題中的警告信息完全相同? –

+0

當'QueryInterface'爲'pInt'賦值時,它使用的左值是什麼類型?如果該左值與DecodingFramework :: IVariableFramerate *不兼容,則更新後的代碼仍然違反別名規則。 –

回答

4

這也是爲什麼說謊有關指針類型的編譯器是壞:

struct SomeClass { int a; }; 
SomeClass* global_pointer; 

void open_object(void** result, int x) 
{ 
    cout << global_pointer->a; 
    *result = new SomeClass{x}; 
    cout << global_pointer->a; 
} 

編譯器是完全允許更換由:

auto temp = global_pointer->a; 
cout << temp; 
*result = new SomeClass{x}; // according to the Standard, the compiler is allowed to assume this line CANNOT change global_pointer, because the type is wrong 
cout << temp; 

如果你再調用

open_object((void**)&global_pointer); 

那麼你可能會對結果感到驚訝。

相關問題