1. Си / Говнокод #10307

    +136

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    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, 17 Мая 2012

    Комментарии (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;
            }
            Ответить

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