bag или нет в VS2003?

Тема в разделе "WASM.BEGINNERS", создана пользователем wsd, 19 авг 2007.

  1. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Привет!

    Писал мелкую утилитку по переводу бинарика в С хидер.
    Раньше с этим не сталкивался ,но оказывается printf и все её сёстры байты расценивают
    только как символы.И приходится преобразовывать это в нечто покрупнее чтобы она сформатировала его HEX значение.
    Вот тут и началось.
    Если char преобразовать в unsigned short - VS2003 она расширяет его знаково!и printf
    соответственно мне назаписывал 4байтных(c первыми FF) а не 2байтных значений!
    Делал ASM листинг и там заместо MOVSZ торчит MOVSX!!!!
    Выкрутился так:
    (unsigned short) my_byte & 0xFF
    Но это-же....

    Действительно в VS2003 есть такой баг?
    Или какая-то сволоч мне VS2003 какой-то подлянкой пропатчила?
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ты о чём?
    printf("%02X", your_byte); прекрасно работает.
     
  3. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Спасибо за поддержку!

    Да твой вариант работает.
    Но глюк то в неправильном преобразовании типов.
    Когда тип преобразуется в больший с UNSIGNED он не должен расширятся знаком!
    Мой и твой вариант просто кладут на этот баг - а он ЕСТЬ.

    Спасибо.
     
  4. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Кстати поспешил насчёт твоего варианта.

    Такой код:

    char x=220;
    printf("%02X", x);

    Даёт у меня:

    FFFFFFDC
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    wsd
    У тебя c - signed char.
    Пиши так:

    unsigned char c = 220;
    printf("%02X\n", c);

    или

    char c = 220;
    printf("%02X\n", (unsigned char) c);
     
  6. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Понял.
    С unsigned char всё нормально работает!
    Спасибо!

    Но основная проблема что
    signed char sc = 220;
    unsigned short us = (unsigned short) sc

    ДЕЛАЕТ РАСШИРЕНИЕ ЗНАКОМ!!!! А НЕ НУЛЁМ!!!!

    Сейчас перекинул все в GCC(Linux) и ...
    В С получается нет беззнакового расширеня.
    Всёравно к чему приводиш к signed or unsigned он расширяет со знаком.
    Правильно?
     
  7. mathio

    mathio New Member

    Публикаций:
    0
    Регистрация:
    16 июн 2007
    Сообщения:
    110
    Не болтайте ерундой, транслятор всё правильно делает.
    На примере
    Код (Text):
    1. unsigned short us = (unsigned short) sc
    1. sc имеет тип signed char, потому когда вы пишите sc справа от знака равно, транслятор генерирует код по извлечению значения из переменной sc и приводит его к длине машинного целого(например, 32 бита на 32 битных машинах), для того, чтобы все дальнейшие вычисления были правильными. Т.е. например, в стеке(памяти) лежит байтовое значение 0xFE, компилятор знает, что оно знаковое, читает его с помощью movsx, тем самым расширяя знак до целого, для того чтобы в регистре оказалось именно (-2), а не 254.
    2. После этого вы приводите sc к типу unsigned short, тоесть транслятором генерируется код, который просто сохраняет младшие 16 бит. Например, таким образом sc&0xFFFF. Соотв-но у вас и получается, что все старшие биты младшего 16-ти битного слова установлены.

    Вообще в таком случае грамотнее приводить типы через указатели
    Код (Text):
    1. #include <stdio.h>
    2.  
    3. void main()
    4. {
    5.   signed char c = -2;
    6.   printf("%08x\n", c);
    7.   printf("%08x\n", *(unsigned char *)&c);
    8. }
     
  8. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    mathio

    Молодец!
    А приводить по указателям красивый ход!
    Всем спасибо!
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    printf("%08x\n", (unsigned short)(unsigned char) -2);

    проще..
     
  10. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    char - это знаковый тип, и расширяется знаково. Используй unsigned char - все будет ок.