стандарты и приведение типов в Си

Тема в разделе "WASM.ZEN", создана пользователем Booster, 26 июл 2005.

  1. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Всем привет.

    1) приведение типов.

    AFAIK размер смещения указателей в Си, в отличие от Ассемблера:derisive:, происходит от типа указателя. То-есть
    Код (Text):
    1. (long*)pointer+1
    приведёт к смещению на DWORD. Но если мне нужно смещение в байтах, а результат long. Писал для этого:
    Код (Text):
    1. *(long*)((char*)pointer+1)
    2.  


    Но как-то монструозно и искусственно. Может можно проще?



    2)О стандартах. У Borland и Microsoft, активно применяются типы DWORD, BYTE и тд. Но у меня gcc такого не понимает. А применять long, int не хотелось бы, так как их размер варьируется от машины и компилятора.



    З.Ы. Сильно не пинайте, в сях не очень силён.
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    1) используй unsigned char* pointer например

    2) посмотри определения в WinDef.h. Кто мешает использовать их в gcc?
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    IceStudent



    Спасибо, втупил по полной.





    Но что это означает, что unsigned long всегда будет DWORD?.







    Таким образом что, тип приведётся автоматически, с извлечением DWORD данных? Что-то не пойму. Можно пример.
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine


    нет, это DWORD всегда будет unsigned long (32бита)



    1) указатель будет на однобайтовые данные, будет как в асме арифметика. если нужно будет извлечь 4 байта, то потребуется приведение:

    DWORD d = *((DWORD*)pointer);
     
  5. rgo

    rgo New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    87
    обычно в системных бтблиотеках присутствует хедер с определениями типов конкретных размеров, у M$ это BYTE, WORD, DWORD; в GNU libc -- uint8_t, int16_t и тп. Надо просто поискать.

    а насчёт инкремента указателя, я бы сделал так:

    union {

    char *pc;

    long *pointer;

    };

    ...

    pc ++;

    printf ("%ld", *pointer);
     
  6. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    А как насчёт обычного макро-расширения?

    И на его базе более узкоспециальные макросы:
    Код (Text):
    1.  
    2. #define PTR_MOVE(p,type,bytes)  (type*)(((unsigned char*)(p))+(bytes))
    3. #define PLONG_MOVE(p,bytes)  PTR_MOVE(p,long,bytes)
    4. #define PLONG_MOVE_ME(p,bytes)  p=PLONG_MOVE(p,bytes)
    5.  
    6. long* p = ...;
    7.  
    8. p = PLONG_MOVE (p, 5); // Move it 5 bytes forward
    9. PLONG_MOVE_ME (p, -3); // Move it 3 bytes back
    10. PLONG_MOVE_ME (p, sizeof (int)); // Кросс-платформенно даже!
     
  7. SDragon

    SDragon New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2005
    Сообщения:
    133
    Адрес:
    Siberia
    AsmGuru62 Отличная идея! В winnt.h есть несколько макросов (FIELD_OFFSET, RTL_CONTAINS_FIELD, CONTAINING_RECORD, RTL_NUMBER_OF), выполняющих подобные задачи, но именно такого нет.
     
  8. Fallout

    Fallout New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2004
    Сообщения:
    94
    Адрес:
    Russia
    >>А применять long, int не хотелось бы

    long и подорузомевает long int :)) ибо по умолчанию если тип не определяешь то он int... :) киньте в меня кирпичем если я не прав.. но по стандарту так должно быть

    long int и long - одно и тоже...
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    char <= short int (aka short) <= int <= long int (aka long)
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    AsmGuru62

    Спасибо за макросы.



    rgo



    Да, но хотелось бы пользоваться единым стандартом типов, ведь называют же Си портируемым ассемблером.:derisive:.



    И насчёт размера типов, разве оговаривается, что long всегда 4 байта. Если в стандарте это указано, тогда не прав. Но я вседа думал, что это зависит от конкретного компилятора. Ведь есть версии где int - 16 бит, а есть где 32. И не известно как это будет дальше. А если нужно всегда работать именно с определённым размером данных, не зависимо от платформы и компилятора? Или всегда придётся шаманить с хедерами?
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine


    Нет. Указано только то, что я привёл выше.





    Тогда переопределять типы на __intN или uintN_t, или что-то ещё, в зависимости от компилятора, и использовать переопределённые, типа BYTE или uint8.
     
  12. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    AFAIK типы вроде uintN_t включены в стандарт С99 (stdint.h)
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    S_T_A_S_

    Что-то не видать этого файла в MSVC.



    да, его нет.
     
  14. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    выходит компилятор не соответствует стандарту С99. В MSVC 2005 beta 2 его тоже нет.
     
  15. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    S_T_A_S_

    Ну и как она тебе эта 2005?
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    EvilsInterrupt

    Уфф, загляни на рсдн. Там чуть ли не каждый день по вопросу, аналогичным твоему :)
     
  17. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    EvilsInterrupt

    2005 глючная. поиск в MSDN не работает :dntknw:( разбираться пока время нет
     
  18. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
  19. tylerdurden

    tylerdurden New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    322
    Кстати обнаружил дикий глю в BC5 (тот что можно на шару скачать) - определяю BYTE как usigned char а работает с ним он как с signed (везде повставлял movsx собака)... Убил неделю пока понял в чем дело...
     
  20. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    не нужно использовать драные компиляторы ;) на шару много чего скачать дают, а msvs 2005 присылают по почте (4 DVD)