GCC警告“解除引用类型 - 惩罚指针将破坏严格别名规则”

时间:2013-08-27 15:25:52

标签: c++ c gcc

我使用QueryInterface函数,它将根据IID返回指定接口上的指针。

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**之外的地址指针时? 真的存在问题吗?我不明白这种警告背后的理性。

1 个答案:

答案 0 :(得分: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);

然后你可能会对结果感到惊讶。