булево — C ++: присвоение результата побитового И логическому

У меня есть следующий цикл в C ++, скомпилированный с g ++ 4.1.2:

while(1) {
int status = getStatus();
bool firstOk = status & 0x1;
bool secondOk = status & 0x2;
if(firstOk != m_firstOk) {
logStatus(1, firstOk);
m_firstOk = firstOk;
}
if(secondOk != m_secondOk) {
logStatus(2, secondOk);
m_secondOk = secondOk;
}

sleep(1);
}

Обратите внимание, что logStatus () получает свои параметры по значению, поэтому параметр не изменяется. m_firstOk и m_secondOk — это, конечно, атрибуты члена bool.

Это работало нормально до сих пор. Я получил сообщение, что он не обнаружил, когда firstOk изменился. Я подключен к запущенному процессу с помощью GDB. Это было в строке сна (), и я удивился, увидев следующее:

(gdb) p m_firstOk
$1 = true
(gdb) p m_secondOk
$2 = true
(gdb) p firstOk
$3 = 244

WTF? Как firstOk может быть 244, когда оно должно быть результатом побитового И с 0x1? Я знаю, что логическое значение на самом деле хранится как целое число, но как можно проигнорировать мое побитовое И? Так как это 244, оно оценивается как истинное, когда оно должно быть ложным, что является причиной проблемы.

Разве не присваивает результат побитового И логическому сейфу? Это ошибка GCC? Или я должен сделать что-то вроде следующего?

bool firstOk = (status & 0x1) ? true : false;

Заранее спасибо.

4

Решение

Локальные переменные firstOk а также secondOk не «живы», когда вы достигнете sleep() звоните, так что даже если они имел Выделенные слоты стека, вполне возможно (и действительно вполне вероятно), что их значения больше нигде не хранятся.

Если вам нужно отладить любую из этих переменных, вам нужно либо

  1. Повторно объявить их как static, который будет выделять им постоянное хранилище вне стека
  2. Переместить декларацию firstOk а также secondOk на внешний охват. (Обратите внимание, что этого может быть недостаточно, если вы не переместите их в область действия файла.)
  3. Скопируйте значения firstOk а также secondOk чтобы постоянные переменные или переменные живут во внешней области видимости и проверяют их.

В любом случае, я бы отменил любую из вышеперечисленных мер отладки, как только вы завершите процесс отладки. 🙂

Что касается вашего последнего вопроса, утверждение bool firstOk = status & 0x1 отлично, как и заявление, которое следует за этим secondOk, Назначение int к bool принуждает нулевые / ненулевые значения к false а также true,

Что касается вашей реальной ошибки (как-то вы пропустили переход на firstOk), Я не вижу, где вы могли потерять его в этом коде. Эта часть кода выглядит нормально. Возможно ли, что ваш getStatus() функцию нужно вызывать чаще, чем раз в секунду? Может что-нибудь еще написать m_firstOk или же m_secondOk? Их объявления не показаны, так что, по-видимому, они существуют во внешней области видимости.

2

Другие решения

Единственный возможный способ — это если:

1) стек как-то перезаписан.

2) Значение временного значения не так существенно, как только вы попадаете в спящую линию, поэтому компилятор больше не отслеживает его, так что слот памяти мог использоваться для чего-то другого!

Если он сначала работает, а потом начинает работать неправильно, то, скорее всего, это не ошибка компилятора для этого раздела кода.

0

Правильное назначение должно быть:

bool firstOk = (status & 0x1) == 0x01;

Или вообще:

bool flag = (value & mask) == mask;
-1
По вопросам рекламы [email protected]