Использование memcmp
обычно не очень хорошая идея.Давайте начнем с более сложного и продолжим работу.
Хотя вы упомянули int
и double
, я сначала хочу сосредоточиться на memcmp
в качестве общего решения, такого как сравнениемассивы типа:
struct {
char c;
// 1
int i;
// 2
}
Основная проблема заключается в том, что реализации могут свободно добавлять заполнение к структурам в местоположениях 1 и 2, что делает байтовое сравнение потенциально ложным, даже если важные биты идеально совпадают.
Теперь до двойников.Вы могли бы подумать, что это было лучше, так как там нет отступов.Однако есть и другие проблемы.
Первая - обработка значений 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
, иллюстрирующую разницу.
Второй - обработка плюс и минус ноль.Их следует считать равными для целей сравнения, но, поскольку битовые комбинации различны, memcmp
скажет, что они различны.
Изменение объявления / инициализации d1
и d2
в приведенном вышекод для:
double d1 = 0.0, d2 = -d1;
прояснит это.
Итак, если структуры и двойники проблематичны, конечно, целые числа в порядке.В конце концов, они всегда дополняют друг друга, да?
Нет, на самом деле это не так.ИСО обязывает одну из трех схем кодирования целых чисел со знаком, а две другие (дополнения и знак / величина) страдают от аналогичной проблемы, связанной с двойными числами, в том смысле, что существуют как плюс, так и минус ноль.
Итак, в то время каквозможно, их следует считать равными, опять же, битовые комбинации различаются.
Даже для беззнаковых целых чисел у вас есть проблема (это также проблема для знаковых значений).ISO заявляет, что эти представления могут иметь биты значения и биты заполнения, и что значения битов заполнения не определены.
Таким образом, даже для того, что может показаться самым простым случаем, memcmp
может быть плохой идеей.