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

Posted

技术标签:

【中文标题】C++:指针和编译器(别名?)优化【英文标题】:C++: pointers and compiler (aliasing?) optimization 【发布时间】:2014-01-08 13:57:21 【问题描述】:

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

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 也无济于事,所以我完全一头雾水。当然,我可以在禁用优化的情况下构建项目,但我真的很想了解发生了什么。 提前致谢。

【问题讨论】:

为什么不在IfaceData->Data 上使用address-of operator 如何找到数据的结尾?看起来代码一直在继续......继续......继续......(我个人会怀疑未定义的行为,除非有其他任何明确证据。) IfaceData 是一种类型。你怎么能做到&IfaceDataIfaceData->Data?你能发布实际代码吗?此外,您将指针视为int32_t *,然后将其作为int * 传递? 另外,第三方如何分配以IfaceData->Data开头的内存块?它是一个数组,而不是一个指针。你的意思是它分配类似malloc(sizeof(IfaceData) + some_extra_bytes) 的东西,然后用结果覆盖给定的IfaceData * @Shahbaz 对不起,这是一个错字,第一行必须读作typedef struct int32_t DataLen; char Data[1]; MTEMSG; MTEMSG *IfaceData; 至于分配内存 - 它可能按照你描述的方式工作,我不太确定 【参考方案1】:

经过一些研究,我发现我在 gcc 调用中同时拥有 -std=gnu++11-std=c++1x 以进行发布构建。在我删除 -std=gnu++11 之后,一切都像魅力一样。

【讨论】:

以上是关于C++:指针和编译器(别名?)优化的主要内容,如果未能解决你的问题,请参考以下文章

C++类体系中this指针不能改变指向吗?

指针与引用

c++ 中的 final 关键字是不是允许额外的编译器优化?

优化C++软件

C++之引用

编译器可以通过指向易失性的指针优化存储吗? [复制]