编译器躺着也中枪

很多程序员喜欢指出编译器这样那样的问题,让我们来谈谈这个话题。

当程序员说,这是编译器导致的错误,可以告诉你,99%的情况下是他在撒谎。你会发现以下问题:
1.数组溢出
2.变量未初始化
3.打印错误
4.多线程的同步问题
5.非volatile变量
6.代码导致未定义的错误
等等

许多人知道这些问题,但就是不停的怪罪编译器。编译器当然也有可能包含错误,但这个概率非常低。用了多年的VC++
,只碰到过一次它产生不正确的汇编代码。

一个建议

在开始指责编译器之前,认真全面的检查你的代码,尽快消除你代码的错误,这样也不会因为一个低级问题被其他程序员取笑。

这里是ffdshow的一个项目片段

TprintPrefs::TprintPrefs(IffdshowBase *Ideci,
const TfontSettings *IfontSettings)
{
memset(this, 0, sizeof(this)); // 这语句在优化之后看起来没用

dx = dy = 0;
isOSD = false;
xpos = ypos = 0;
align = 0;
linespacing = 0;
sizeDx = 0;
sizeDy = 0;

}

在Debug版本里面所有的变量都是0。在Release版本里面因为错误的优化导致垃圾的出现,我隐约可以听到程序员在骂这个破编译器。

骂完编译器之后,程序员给每个类的成员变量一一赋值。勇气还是战胜了邪恶势力。他/她用他的方法解决了这个问题。

我需要解释的是,memset()函数在这种情况下不起作用的原因是:第三个参数传进去了指针的大小,并非结构体的大小,应该memset(this, 0, sizeof(*this))。

顺便提到的是,是不是memcpy()经常会不奏效。我敢肯定,程序员又在骂编译器是低智商。

void Assign(const AVSValue* src, bool init) {
if (src->IsClip() && src->clip)
src->clip->AddRef();
if (!init && IsClip() && clip)
clip->Release();
// make sure this copies the whole struct!
//((__int32*)this)[0] = ((__int32*)src)[0];
//((__int32*)this)[1] = ((__int32*)src)[1];
memcpy(this,src,sizeof(this));
}

从内容里可以看出,程序员想要复制内存。当程序员想要复制的结构体正好是8字节的时候,在64位系统里面正好可以运行。

依然还是,sizeof(*this)。

结论:出现错误,还是排查你的代码吧。

 

文章来源:大爱数据