Предпочтительный способ сравнения структуры с нулем

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

  • сравнить каждый элемент с нолем, в результате получится 40 операторов if.
  • выделение аналогичной структуры, которая уже обнулена и memcmp она со структурой.
  • обертывание структуры в объединении с типом, достаточно большим, чтобы покрыть все его.

например

typedef union {
  struct {
    uint8_t a;
    uint8_t b;
    }
  uint16_t c;
 } STRUCTURE_A;

а затем сравнивая его с нолем.

Я хотел бы знать, что вы думаете об этих решениях, какие из них вы найдете наиболее быстрыми и эффективными.
И если вы предпочитаете лучший подход, скажите мне...
Спасибо.

Ответ 1

Сравните каждый член структуры с 0.

Это единственный безопасный способ сравнения двух структурных объектов (даже если один из объектов структуры имеет все члены, установленные на значение 0). Не используйте memcmp для сравнения структуры, значение байтов заполнения в структуре не указано. Также обратите внимание, что не разрешается использовать оператор == с операндами структурных объектов.

См. ссылку c-faq для сравнения объектов структуры:

Q: Можно ли автоматически сравнивать структуры?

Ответ 2

Если размер вашей структуры равен <= размер слова процессора, вы можете сделать свой союзный трюк, однако любой хороший компилятор должен сделать это автоматически, так как он будет сжимать if, позволяя ясность, но сохраняя производительность до нуля.

Ответ 3

Для ясности кода и, как указывали другие, чтобы избежать проблем, вызванных заполнением, проверка каждого элемента была бы лучше.

Для скорости, начните с чего-то подобного, который просто проверяет каждый байт, чтобы увидеть, равен ли он нулю.

int iszero(void * ptr, int bytes )
{
   char * bptr = (char*)ptr;
   while( bytes-- )
     if( *bptr++ )
         return 0;
  return 1;
}

Затем оптимизируйте выполнение сравнений с выравниванием по словам. Ознакомьтесь с новостями о реализации таких вещей, как strlen() и memcpy() для примеров того, как это делается.