Chromium1 2 3 4 5 6 7 8 9 | if (access & FILE_WRITE_ATTRIBUTES)
output.append(ASCIIToUTF16( "\tFILE_WRITE_ATTRIBUTES\n" ));
if (access & FILE_WRITE_DATA)
output.append(ASCIIToUTF16( "\tFILE_WRITE_DATA\n" ));
if (access & FILE_WRITE_EA)
output.append(ASCIIToUTF16( "\tFILE_WRITE_EA\n" ));
if (access & FILE_WRITE_EA)
output.append(ASCIIToUTF16( "\tFILE_WRITE_EA\n" ));
break ;
|
最后两行相同。
ReactOS1 2 3 | if (*ScanString == L '\"' ||
*ScanString == L '^' ||
*ScanString == L '\"' )
|
Multi Theft Auto1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class CWaterPolySAInterface
{
public:
WORD m_wVertexIDs[3];
};
CWaterPoly* CWaterManagerSA::CreateQuad (....)
{
....
pInterface->m_wVertexIDs [ 0 ] = pV1->GetID ();
pInterface->m_wVertexIDs [ 1 ] = pV2->GetID ();
pInterface->m_wVertexIDs [ 2 ] = pV3->GetID ();
pInterface->m_wVertexIDs [ 3 ] = pV4->GetID ();
....
}
|
最后一行冗余代码来自于惯性粘贴。数组的大小是3。
Source Engine SDK1 2 3 4 5 6 | intens.x=OrSIMD(AndSIMD(BackgroundColor.x,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.x));
intens.y=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.y));
intens.z=OrSIMD(AndSIMD(BackgroundColor.y,no_hit_mask),
AndNotSIMD(no_hit_mask,intens.z));
|
程序员忘记把最后一行的中的“BackgroundColor.y”改成“BackgroundColor.z”。
Trans-Proteomic Pipeline1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | void setPepMaxProb(....)
{
....
double max4 = 0.0;
double max5 = 0.0;
double max6 = 0.0;
double max7 = 0.0;
....
if ( pep3 ) { ... if ( use_joint_probs && prob > max3 ) ... }
....
if ( pep4 ) { ... if ( use_joint_probs && prob > max4 ) ... }
....
if ( pep5 ) { ... if ( use_joint_probs && prob > max5 ) ... }
....
if ( pep6 ) { ... if ( use_joint_probs && prob > max6 ) ... }
....
if ( pep7 ) { ... if ( use_joint_probs && prob > max6 ) ... }
....
}
|
程序员忘记把最后一个判断中的“prob > max6”改为“prob > max7”。
SeqAn1 2 3 4 5 6 | inline typename Value<Pipe>::Type const & operator*() {
tmp.i1 = * in .in1;
tmp.i2 = * in .in2;
tmp.i3 = * in .in2;
return tmp;
}
|
SlimDX1 2 3 4 5 6 7 | for ( int i = 0; i < 2; i++ )
{
sliders[i] = joystate.rglSlider[i];
asliders[i] = joystate.rglASlider[i];
vsliders[i] = joystate.rglVSlider[i];
fsliders[i] = joystate.rglVSlider[i];
}
|
最后一行应该用rglFSlider。
Qt1 2 3 4 5 6 7 8 9 10 11 12 13 14 | if (repetition == QStringLiteral( "repeat" ) ||
repetition.isEmpty()) {
pattern->patternRepeatX = true ;
pattern->patternRepeatY = true ;
} else if (repetition == QStringLiteral( "repeat-x" )) {
pattern->patternRepeatX = true ;
} else if (repetition == QStringLiteral( "repeat-y" )) {
pattern->patternRepeatY = true ;
} else if (repetition == QStringLiteral( "no-repeat" )) {
pattern->patternRepeatY = false ;
pattern->patternRepeatY = false ;
} else {
}
|
最后一块少了‘patternRepeatX’。正确的代码应该是: 1 2 | pattern->patternRepeatX = false ;
pattern->patternRepeatY = false ;
|
ReactOS1 2 3 4 | const int istride = sizeof(tmp[0]) / sizeof(tmp[0][0][0]);
const int jstride = sizeof(tmp[0][0]) / sizeof(tmp[0][0][0]);
const int mistride = sizeof(mag[0]) / sizeof(mag[0][0]);
const int mjstride = sizeof(mag[0][0]) / sizeof(mag[0][0]);
|
‘mjstride’永远等于1。最后一行应该是: 1 | const int mjstride = sizeof(mag[0][0]) / sizeof(mag[0][0][0]);
|
Mozilla Firefox1 2 3 4 5 6 7 | if (protocol.EqualsIgnoreCase( "http" ) ||
protocol.EqualsIgnoreCase( "https" ) ||
protocol.EqualsIgnoreCase( "news" ) ||
protocol.EqualsIgnoreCase( "ftp" ) || <<<---
protocol.EqualsIgnoreCase( "file" ) ||
protocol.EqualsIgnoreCase( "javascript" ) ||
protocol.EqualsIgnoreCase( "ftp" )) { <<<---
|
最后的“ftp”很可疑,它之前已经被比较过了。
Quake-III-Arena1 2 3 | if (fabs(dir[0]) > test->radius ||
fabs(dir[1]) > test->radius ||
fabs(dir[1]) > test->radius)
|
dir[2]的值忘记检查了。
Clang1 2 3 4 5 6 7 8 | return (ContainerBegLine <= ContaineeBegLine &&
ContainerEndLine <= ContaineeEndLine &&
(ContainerBegLine != ContaineeBegLine ||
SM.getExpansionColumnNumber(ContainerRBeg) <=
SM.getExpansionColumnNumber(ContaineeRBeg)) &&
(ContainerEndLine != ContaineeEndLine ||
SM.getExpansionColumnNumber(ContainerREnd) >=
SM.getExpansionColumnNumber(ContainerREnd)));
|
最后一块,“SM.getExpansionColumnNumber(ContainerREnd)”表达式在跟自己比较大小。
MongoDB1 2 3 4 5 6 7 8 9 | bool operator==(const MemberCfg& r) const {
....
return _id==r._id && votes == r.votes &&
h == r.h && priority == r.priority &&
arbiterOnly == r.arbiterOnly &&
slaveDelay == r.slaveDelay &&
hidden == r.hidden &&
buildIndexes == buildIndexes;
}
|
程序员把最后一行的“r”忘记了。
Unreal Engine 41 2 3 4 5 6 7 8 | static bool PositionIsInside(....)
{
return
Position.X >= Control.Center.X - BoxSize.X * 0.5f &&
Position.X <= Control.Center.X + BoxSize.X * 0.5f &&
Position.Y >= Control.Center.Y - BoxSize.Y * 0.5f &&
Position.Y >= Control.Center.Y - BoxSize.Y * 0.5f;
}
|
最后一行中,程序员忘记了两个地方。首先,“>=”应改为“<=”,其次,减号应改为加号。
Qt1 2 3 4 5 6 | qreal x = ctx->callData->args[0].toNumber();
qreal y = ctx->callData->args[1].toNumber();
qreal w = ctx->callData->args[2].toNumber();
qreal h = ctx->callData->args[3].toNumber();
if (!qIsFinite(x) || !qIsFinite(y) ||
!qIsFinite(w) || !qIsFinite(w))
|
最后一个qlsFinite中,传入参数应该是‘h’。 OpenSSL1 2 3 4 5 6 7 8 | if (!strncmp(vstart, "ASCII" , 5))
arg->format = ASN1_GEN_FORMAT_ASCII;
else if (!strncmp(vstart, "UTF8" , 4))
arg->format = ASN1_GEN_FORMAT_UTF8;
else if (!strncmp(vstart, "HEX" , 3))
arg->format = ASN1_GEN_FORMAT_HEX;
else if (!strncmp(vstart, "BITLIST" , 3))
arg->format = ASN1_GEN_FORMAT_BITLIST;
|
字符串“BITLIST”长度为7,而非3。 就此打住吧。我举的例子已经够说明问题了吧?
结论 本文告诉你“拷贝-粘贴”大法在最后一个粘贴代码块中出错的概率很可能是其他块的4倍。
这跟人类的心理学有关,与技术水平无关。文中说明了即便是像Clang或者Qt项目中的编程高手也会犯这种错误。
我希望这个现象的发现对于程序员们有所帮助,也许可以促使他们去研究我们的bug数据库。相信如此有助于在这些错误中发现新的规律并总结出新的编程建议。 |