Няшная / Говнокод #10307 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
if ( sectors && sectorsNum )
{
	for ( i = 0; i < ( int )sectorsNum; i++)
	{
		*(unsigned int*)(pl + 4 + 4 + i * 10 ) = sectors[i].originalNum;
		*(pl + 4 + 4 + i * 10 + 4) = 3 ;
		*(unsigned int*)(pl + 4 + 4 + i * 10 + 5 ) = sectors[i].usedNum;	
		*(pl + 4 + 4 + i * 10 + 9) = 4 ;
	}
	*(unsigned int*)(pl + 4 + 4 + i * 10 ) = newSectors;
	*(pl + 4 + 4 + i * 10 + 4) = 0x0b ;
	*(unsigned int*)(pl + 4 + 4 + i * 10 + 5 ) = newSectors * 0x200; // сектора в байты
}

В старых исходниках довольно крупного проекта нашелся сей замечательный отрывок... И очень одинокий коммент...

Запостил: sima sima, (Updated )

Комментарии (10) RSS

    • А если формат структуры, которую они заполняют, требует невыровненных полей?
      Ответить
      • такое чтение и запись слова не по границе слова на некоторых платформах вообще будет приводить к аварийному завершению программы
        если так хочется структуру с невыровненными полями, то надо все хранить в байтовом массиве и отказаться от операции =
        т.е.
        unsigned char mystruct[N]; //где N - sizeof(field1) + sizeof(field2) + sizeof(field3) +...
        
        #define GetUnsignedBitField(array, offset, bitsize)   ...
        #define SetUnsignedBitField(value, array, offset, bitsize) ...
        
        #define Some_GetField1(x)   GetUnsignedBitField(x, 0, 8)
        #define Some_SetField1(x, value)   SetUnsignedBitField(value, x, 0, 8)
        #define Some_GetField2(x)   GetUnsignedBitField(x, 8, 32)
        #define Some_SetField2(x, value)   SetUnsignedBitField(value, x, 8, 32)
        
        Some_SetField1(pl, sectors[i].originalNum);
        Some_SetField2(pl, 3);
        Some_SetField3(pl, sectors[i].usedNum);
        // etc
        тогда получится максимальная кросс-платформенность

        если кросс-платформенности путем таких геморроев (арифметика смещений) не хочется, а хочется чтобы просто не падало, то еще вариант (32-битное выравнивание)
        struct some {
           bitfield1 : 8;
           bitfield2_hi: 24;
        
           bitfield2_lo: 8;
           reserved1: 8;
           bitfield3: 16;
        };
        #define GetBitField2(some)  (some.bitfield2_hi << 8) | some.bitfield2_lo
        #define SetBitField2(value, some)  some.bitfield2_hi = value >> 8, some.bitfield2_lo = value & 0xff

        но тут надо еще посмотреть как компилятор little-endian и big-endian будет размещать битовые поля внутри слова (т.е. если вдруг важно чтобы bitfield2_hi непосредственно соседствовал с bitfield2_lo)
        Ответить
        • Да я согласен, но видимо авторам не нужен был кроссплатформенный код. Т.к. тут не только выравнивание не учтено, но и byte-order.
          Ответить
  • Да я согласен, но видимо авторам не нужен был кроссплатформенный код. Т.к. тут не только выравнивание не учтено, но и byte-order.
    Ответить
  • 1) (pl + 4 + 4 + i * 10) - так нужно, и что бы каждый раз по новому?
    2) sectorsNum data type? Сообщите, пжлста.
    P.S. Ябы этому дяде, с не выравненными полями, поля то, повыравнивал.
    Ответить
    • А если это формат хранения данных на носителе? Например, на диске?
      Тут только одна таблетка: декларируется соответствующая упакованная структура с полным описанием полей и делается каст указателя к ней. А затем уже выдёргиваются значения по полям.
      Ответить
      • >>упакованная структура с полным описанием полей
        Это нормально. Так и делают.
        >>А затем уже выдёргиваются значения по полям.
        sectorsNum не является полем структуры, что наверняка заметили.
        Или вы о чём то другом?

        Проверяю предположение: sectorsNum хранится в (signed/unsigned)char — больше не нужно. В цикле -- численное значение количества секторов.
        Ответить
        • Сам спросил, сам и отвечу.
          #include <stdio.h>
          
          struct block_info {  int i; char c; } blk_info;
          #define  sectorsNum   blk_info.i
          #define  sectorsChar   blk_info.c
          
          int main()
          {
          sectorsNum  = 5;
          sectorsChar  ='A';
          printf("i=%d\tc=%c\n", sectorsNum, sectorsChar);
          return 0;
          }
          Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8