C ++:指针和编译器(别名?)优化

时间:2014-01-08 13:57:22

标签: c++ gcc optimization

我在编译器优化方面遇到了麻烦,所以我需要一些帮助。 我有以下代码:

typedef struct {
   int32_t  DataLen;
   char     Data[1];
} MTEMSG; 
MTEMSG *IfaceData;
int Interface = MTEStructure2(ConnectionHandle, &IfaceData); 
int32_t * pointer = (int32_t *)IfaceData->Data;
ReadFromBuf(pointer);

MTEStructure2是第三方函数,它分配以IfaceData->Data开头且长度为IfaceData->DataLen的内存块。该缓冲区由多个1字节字符行组成,每行前面都有该行的长度(4字节整数)。所以我有一个阅读一行的功能:

int * MTEGetString(int * pointer, std::string & result) 
{
    int datalen = 0;
    datalen = *pointer;
    char * data;
    data = (char *) (pointer + 1);
    result = std::string(data, datalen);
    pointer = (int *)(data + datalen);
    return pointer;
}

ReadFromBuf这样调用:

int* ReadFromBuf(int * pointer)
{
    std::string name="", caption="", description="";
    pointer = MTEGetString(pointer, name);
    pointer = MTEGetString(pointer, caption);
    pointer = MTEGetString(pointer, description);
    // etc
}

在调试模式下一切正常(我在WinXP下使用Qt 5.0.1和gcc 4.7.2)。但是只要我切换到发布模式,程序就会在result = std::string(data, datalen);崩溃,因为datalen(到那时整个缓冲区,我猜)是无效的。在禁用发布版本的优化(QMAKE_CXXFLAGS_RELEASE -= -O2)后,一切正常。

我已经完成了一些阅读,而我发现的最接近的是一个别名优化。但即使使用-Wall选项,编译器也不会发出警告,并且-fno-strict-aliasing没有帮助,所以我完全处于黑暗中。当然,我可以使用禁用优化来构建项目,但我真的想了解发生了什么。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

经过一番研究,我发现我在gcc中同时拥有-std=gnu++11-std=c++1x来进行发行版本的构建。在我删除-std=gnu++11之后,一切都像灵符一样。