2015-07-20 3 views
3

API предоставляет функцию signed char getDirection();, которая возвращает 1 для «вперед», 0 для «неподвижных», -1 для «назад».Как сравнить Signed Char с литеральной константой?

И, конечно же, как описано в thesequestions, простое сравнение:

if(getDirection() == -1) { ... } 

терпит неудачу. Хорошо, я понимаю, почему он терпит неудачу. Но я просто не могу найти, как заставить его работать! Я попытался литьем левой стороны (int), правая сторона в (signed char), еще нада ...

редактировать:

signed char a = getDirection(); 
printf("%d\n",(int) a); 
printf("%d\n",(int) getDirection()); 

Результатов:

-1 
255 

edit2: на заказ:

const signed char getDirection(uchar d) 
{ 
    if(d >= config.directional_inputs.channelCount) return -2; 

    return shm->input_state.directional_inputs[d].direction; 
} 
+0

@ AlexD: Желаю.Ну, на самом деле тестовый оператор находится в формате 'printf (" val:% d, сравнение:% d ", getDirection(), (getDirection() == DIRECTION_BACK));' где константа '#define DIRECTION_BACK -1' –

+3

Ваш код верен. Проверьте, действительно ли 'getDirection()' возвращает -1. Покажите результат вашего 'printf'. Также покажите свой реальный код, может быть, просто бродячий ';' где-то. –

+0

@MichaelWalz: Выход: "val: -1, compare: 0". Коллега подозревает ошибку компилятора. –

ответ

0

Если вы уверены, что getDirection() действительно возвращает сиг ned char, он должен работать, так как подписанный символ 0xff должен быть правильно продвинут до значения -1.

Если вы не знаете, вы могли бы попытаться написать

int dir = getDirection(); 
// optionnally for extensive tests : fprintf(stderr, "getDirection : %d\n", dir); 
if ((dir == -1) || (dir == 255)) { ... } 

255 ловил любую проблему преобразования, например getDirection() возвращает подписанный символ ... что ваша последняя правка предлагает ...

+0

Это своего рода решение для взлома ... –

+0

@MichaelWalz: Это так. Но однажды мне пришлось использовать что-то подобное для библиотеки, которая вернула «char», и мне пришлось использовать ее на двух платформах, где char был подписан на одном и без знака на другом. Я уже видел (плохо написанный) код, где doc сказал «подписанный символ» и код содержал только «char», потому что программист думал, что то, что он имел в своей системе (char = signed char), было стандартным, тогда как в стандарте указано, что это зависит от реализации. –

+0

@SergeBallesta: Мой личный подход заключается в том, что «char» всегда означает букву ASCII. Если это число, оно должно быть обозначено как «подписанный» или «беззнаковый». –

0

It похоже, что в GetDirection часть return shm->input_state.directional_inputs[d].direction; Выполняется. Каков тип этого элемента direction? Я не уверен насчет рекламных акций здесь, но если это unsigned char, он может быть просто скопирован в регистр возврата ax и возвращен. То есть, расширение знака не выполняется, а ax - 0x000000ff. ff присваивается signed char a, что является правильным, и когда a используется в вызове printf, он получает надлежащим образом расширенный знак. Поэтому расширение знака должно быть сделано в операторе возврата GetDirection, где, по-видимому, это не сделано.

Попробуйте изменить его return (signed char)shm->input_state.directional_inputs[d].direction;

+0

'direction' является' signed char' все равно, и он является первым в цепочке присвоений, получая буквальный '-1', когда входные порты объединяются в конфигурацию« назад ». –

+0

По-прежнему выглядит так: 'GetDirection' не расширяет знак. Проверьте его с помощью отладчика. –

0

Это очень странно.

Во-первых, использование разных компиляторов может иметь значение. У них могут быть разные правила, как предполагается, что подписанный символ должен быть возвращен. Предположим, что компилятор для компиляции функции предполагает, что подписанный символ возвращается как 8 бит в 32-битном регистре, а остальные биты нулевые или неопределенные - -1 возвращается как 00000000 00000000 00000000 11111111. Компилятор для вызова предполагает, что подписанный символ возвращается как 8 бит в 32-битном регистре, знак расширен, и, следовательно, все 32 бита могут считаться содержащими правильное значение. Так что компилятор считает, что результат равен 255.

Во-вторых, я видел проблемы, когда прототипы и функции не совпадали. Если есть прототип функции где-то, где говорится «char» вместо подписанного символа, это объясняет все. Поскольку проблема странная, я бы попросил компилятор для вывода препроцессора и проверить, не происходит ли что-то странное.

+0

Для современных или достойных компиляторов стандарт ясен 6.3.1.1 §2-3: * Если int может представлять все значения исходного типа (как ограничение по ширине для битового поля ), значение преобразуется к int; в противном случае он преобразуется в unsigned int. Они называются целыми рекламными акциями * и *. Целочисленные акции сохраняют значение, включая знак. Как обсуждалось ранее, рассматривается ли символ 'plain' 'как подписанный, определяется реализацией *. Но соответствует ли TCC? и какая версия стандарта? –

Смежные вопросы