C++ 標準 (5/5) によると、ゼロ除算は未定義の動作です。次に、このコードを考えてみましょう (コンパイラがコードを最適化するのを防ぐために、多くの役に立たないステートメントがあります)。
int main()
{
char buffer[1] = {};
int len = strlen( buffer );
if( len / 0 ) {
rand();
}
}
Visual C++ は、次のif
ようにステートメントをコンパイルします。
sub eax,edx
cdq
xor ecx,ecx
idiv eax,ecx
test eax,eax
je wmain+2Ah (40102Ah)
call rand
明らかに、コンパイラはコードがゼロで除算されることを認識しています。xor x,x
パターンを使用してゼロを設定しecx
、整数除算の 2 番目のオペランドを提供します。このコードは、実行時に「ゼロによる整数除算」エラーを確実に引き起こします。
IMO のようなケース (コードが常にゼロで除算されることをコンパイラが認識している場合) は、コンパイル時エラーの価値があります。標準ではそれを禁止していません。これは、実行時ではなくコンパイル時にそのようなケースを診断するのに役立ちます。
しかし、私は他の何人かの開発者と話をしましたが、彼らは反対しているようです - 彼らの反対は、「作者がゼロで割って... emm... エラー処理をテストしたい場合はどうですか?」というものです。
__declspec(noinline)
Visual C++ 固有の関数デコレータを使用して、コンパイラを認識せずに意図的にゼロで除算することはそれほど難しくありません。
__declspec(noinline)
void divide( int what, int byWhat )
{
if( what/byWhat ) {
rand();
}
}
void divideByZero()
{
divide( 0, 0 );
}
これははるかに読みやすく、保守しやすいものです。「エラー処理をテストする必要がある」ときにその関数を使用でき、他のすべての場合に適切なコンパイル時エラーが発生します。
何か不足していますか?コンパイラがゼロ除算を認識しているコードの発行を許可する必要がありますか?