を使用するmemcmp
ことは、一般的には良い考えではありません。より複雑なものから始めて、そこから下に進みましょう。
int
とについて言及されましたが、まず、型の配列を比較するなど、一般的な解決策としてdouble
集中したいと思います。memcmp
struct {
char c;
// 1
int i;
// 2
}
ここでの主な問題は、実装が場所 1 と 2 の構造体にパディングを自由に追加できることであり、重要なビットが完全に一致していても、バイトごとの比較が潜在的に偽になる可能性があります。
これでダブルスにダウン。そこにはパディングがないので、これはより良いと思うかもしれません。しかし、他にも問題があります。
1 つ目は、値の処理NaN
です。IEEE754 はNaN
、それ自体を含め、他の値と等しくならないように最善を尽くします。たとえば、コードは次のとおりです。
#include <stdio.h>
#include <string.h>
int main (void) {
double d1 = 0.0 / 0.0, d2 = d1;
if (d1 == d2)
puts ("Okay");
else
puts ("Bad");
if (memcmp (&d1, &d2, sizeof(double)) == 0)
puts ("Okay");
else puts
("Bad");
return 0;
}
出力します
Bad
Okay
違いを示しています。
2つ目は、プラスマイナスゼロの扱いです。これらは比較のために等しいと見なされるべきですが、ビットパターンが異なるため、異なるmemcmp
と言えます。
上記のコードのd1
との宣言/初期化を次のように変更します。d2
double d1 = 0.0, d2 = -d1;
これを明らかにします。
したがって、構造体と double に問題がある場合は、整数は問題ありません。結局のところ、それらは常に 2 の補数ですよね?
いいえ、実際にはそうではありません。ISO は、符号付き整数の 3 つのエンコーディング スキームの 1 つを義務付けており、他の 2 つ (1 の補数と符号/大きさ) は、プラスとマイナスの両方のゼロが存在するという事実である double と同様の問題に悩まされています。
そのため、それらは等しいと考えられるべきですが、やはりビット パターンは異なります。
符号なし整数の場合でも問題があります (符号付きの値でも問題になります)。ISO は、これらの表現には値ビットとパディング ビットを含めることができ、パディング ビットの値は指定されていないと述べています。
そのため、最も単純なケースのように見える場合でもmemcmp
、悪い考えになる可能性があります。