Могу ли я использовать memcmp для проверки структуры на ненулевые члены?

Я использую большую структуру со многими членами, и я хотел бы простой способ быстро увидеть, если какой-либо из членов ненулевой. я знаю это memcmp() Не следует использовать для сравнения двух структур на равенство (как описано здесь: Как вы сравниваете структуры на равенство в C?), но я надеюсь, что, сравнивая структуру с блоком памяти, который был установлен в 0, это может Работа.

Например, предположим, у меня есть некоторая структура:

typedef struct {
    int Int1;
    int Int2;
    int Int3;
} MyInts;

Я создаю переменную из этой структуры:

MyInts MyStruct = {0};

На протяжении всего выполнения моей программы члены MyStruct обычно будет 0, но иногда может быть временно установлено на ненулевое значение. Я хочу быстро проверить, есть ли в MyStruct ненулевые Могу ли я использовать memcmp() как ниже?

// Create empty struct to test against
MyInts EmptyStruct = {0};

// Make sure entire memory block of test struct is cleared
memset(&EmptyStruct, 0, sizeof(MyInts));

// Compare MyStruct to EmptyStruct to see if any non-zero members exist
int result = memcmp(&MyStruct, &EmptyStruct, sizeof(MyInts));

2 ответа

Решение

Вы не можете сделать это в общем случае, потому что структуры могут иметь заполнение между полями и в конце структуры, и содержимое байтов заполнения не гарантируется (может быть неинициализированным мусором).

Если обе сравниваемые структуры были изначально выделены с callocили имел sizeof(thestruct) байтов memset до нуля перед заполнением реальных значений, тогда заполнение будет иметь предсказуемые значения, и memcmp должно сработать. Точно так же, если вы можете гарантировать отсутствие заполнения, то это memcmp должно сработать. Но если один из них не был обнулен, нет, небезопасно.

Конечно, если вы хотите быть "хорошими", вы можете просто сравнить элементы напрямую, возможно, в факторизованной функции, и позволить компилятору обрабатывать оптимизацию, не беспокоясь, если у вас есть ненулевые структуры с плавающими отступами.

Примечание . Второй ответ с наибольшим количеством голосов по указанной вами ссылке. Комментарии к этому ответу также отмечают некоторые крайние случаи, например, floatУ s могут быть значения, которые сравниваются равными, но имеют разные битовые представления, поэтому он не распространяется на все структуры, даже если это так.

Я решил пойти дальше и ответить на свой вопрос для ясности на основе комментариев. Как упоминалось в @MM, заполнение не гарантируется сохранением при присваивании структуры и, возможно, также не сохраняется при присваивании отдельным членом. Поэтому, используя memcmp проверять структуру на ненулевые члены небезопасно.

Как предлагает ShadowRanger, безопасный способ сделать это - индивидуально сравнить каждый элемент структуры.

Другие вопросы по тегам