我查看的WebKit代码是较早的60605版本,没有观察新版本是否已经修复。
在O2优化下,gcc可能存在过度优化的情况。具体来说,WebCore/dom/QualifiedName.h里
inline unsigned hashComponents(const QualifiedNameComponents& buf) { //... const uint16_t* s = reinterpret_cast<const uint16_t*>(&buf); //... } //... QualifiedNameComponents c = { name->m_prefix.impl(), name->m_localName.impl(), name->m_namespace.impl() }; return hashComponents(c);hashComponents里期望通过s能取到buf(即c)里的内容,但是在O2优化下,hashComponents被inline后,c的初始化动作因为乱序优化会被延迟(编译器认为s和c是无关变量),导致从s中取到的是未初始化的值。
类似的情况见:
http://wenku.baidu.com/view/18d193d03186bceb19e8bb1f.html
简单做法是将上述hashComponents里的代码修改为
volatile QualifiedNameComponents tmpBuf = buf; volatile uint16_t* s = reinterpret_cast<volatile uint16_t*>(&tmpBuf);
引入tmpBuf是为了构造一个值拷贝以促进buf完成初始化。volatile关键字必须有,否则tmpBuf可能被优化掉。
关于这个问题的简单测试用例:
#include <stdio.h> typedef struct MyStruct{ short field1; short field2; }MyStruct; int main(int argc, char** argv) { MyStruct obj = {2, 1}; int i = *((int*)(&obj)); printf("%x\n", i); return 0; }
使用O1和O2分别编译同样的代码并运行
[root@localhost test]# gcc -O1 -o test_O1.bin test.c [root@localhost test]# gcc -O2 -o test_O2.bin test.c [root@localhost test]# ./test_O1.bin 10002 [root@localhost test]# ./test_O2.bin 553dd0
两种优化下输出结果不一致,编程时要特别注意这一点。