Перейти к содержанию
    

Переменная типа bool не инвертируется

Добрый день!

IAR 6.40, ARM.

 

Это не работает, переменная не меняет своё значение при каждом вызове функции

void CSmcsCh::ledTask()
{
    ledState = !ledState;
    CSmcsChHal::turnLed( ledState );
}

А это работает

void CSmcsCh::ledTask()
{    
    if( ledState )
    {
        ledState = false;
    }
    else
    {
        ledState = true;
    }
    CSmcsChHal::turnLed( ledState );
}

 

ledState объявлена как приватный члена класса CSmcsCh.

 

Вопрос: кто тупит? :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос: кто тупит? :biggrin:
А что показывает дизассемблер в обоих случаях?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1-й случай.

     55          void CSmcsCh::ledTask()
     56          {
     57              ledState = !ledState;
   \                     _ZN7CSmcsCh7ledTaskEv:
   \   00000000   0xF890 0x103C      LDRB     R1,[R0, #+60]
   \   00000004   0xF081 0x0101      EOR      R1,R1,#0x1
   \   00000008   0xF880 0x103C      STRB     R1,[R0, #+60]
     58          /*    
     59              if( ledState )
     60              {
     61                  ledState = false;
     62              }
     63              else
     64              {
     65                  ledState = true;
     66              }*/
     67              CSmcsChHal::turnLed( ledState );
   \   0000000C   0x4608             MOV      R0,R1
   \   0000000E   0x....             B.N      _ZN10CSmcsChHal7turnLedEb
     68          }

 

2-й случай.

     55          void CSmcsCh::ledTask()
     56          {
     57          //    ledState = !ledState;
     58              
     59              if( ledState )
   \                     _ZN7CSmcsCh7ledTaskEv:
   \   00000000   0xF890 0x203C      LDRB     R2,[R0, #+60]
   \   00000004   0x1E51             SUBS     R1,R2,#+1
   \   00000006   0x4189             SBCS     R1,R1,R1
   \   00000008   0x0FC9             LSRS     R1,R1,#+31
   \   0000000A   0xF880 0x103C      STRB     R1,[R0, #+60]
     60              {
     61                  ledState = false;
     62              }
     63              else
     64              {
     65                  ledState = true;
     66              }
     67              CSmcsChHal::turnLed( ledState );
   \   0000000E   0xF890 0x003C      LDRB     R0,[R0, #+60]
   \   00000012   0x....             B.N      _ZN10CSmcsChHal7turnLedEb
     68          }

 

Сам я в асме не силён, но если мне память не изменяет, то такое поведение ИАРа у меня не в первой. Но раньше как-то не задевало, и обходил это if'ами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нормально выглядит код. EOR - это exclusive OR, то есть вполне годный способ инвертировать младший бит. Вот если у вас в переменную типа bool каким-то образом влезло значение, отличное от 0 или 1, тогда будет сбой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какое значение переменной было до входа в этот кусок программы? Дело в том, что когда идет if, то делается все честно, ноль считается за false, остальное - true. Когда Вы написали !LedState, то компилятор инвертирует только младший бит переменной - имеет право, если его внутреннее представление про true и false этому соответствует. Но если Ваша переменная имела значение, отличное от 0 и 1, то никакой инверсии не будет, т.к. поменяется только младший бит, переменная останется true, т.к. значение будет не 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Переменная никак не инициализировалась...( Сейчас проверю!

Спасибо!!!

 

Работает! Спасибо господа!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я вижу инвертирование в обоих случаях. И не работать в первом случае оно может лишь в том случае, если переменная ledState типа bool изначально содержит какое-то число, отличное от 0 и 1. Тогда при инвертировании младшего бита ее значение так и будет оставаться ненулевым, то есть true.

 

Компилятор снова не виноват, виноват программист, который каким-то левым образом занес в ledState недопустимое для ее типа значение.

 

P.S. ну вот, пока курил - опередили.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилятор снова не виноват, виноват программист, который каким-то левым образом занес в ledState недопустимое для ее типа значение.

Нее, Сергей, я тоже не виноват :rolleyes: :rolleyes: :rolleyes: Я не знал) Вернее знал, что переменные в private не инициализируются, но не сопоставил, что буль это не однобитная переменная в Си/Си++)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нее, Сергей, я тоже не виноват :rolleyes: :rolleyes: :rolleyes:
"Незнание законов не освобождает от ответственности", или, как Учитель заставил написать на первой странице в тетрадке по труду, "Отсутствие на уроке не освобождает от знаний". B)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Незнание законов не освобождает от ответственности", или, как Учитель заставил написать на первой странице в тетрадке по труду, "Отсутствие на уроке не освобождает от знаний". B)

Ну да, век живи - век учись :bb-offtopic:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос: кто тупит? :biggrin:

 

 

если без иннициализации, то должно было бы помочь ledState = !!!ledState; ( с тремя ! )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если без иннициализации, то должно было бы помочь ledState = !!!ledState; ( с тремя ! )
Почему?

 

Результат оператора ! имеет тип bool, неявного преобразования его операнда к int, в процессе обратного преобразования от которого к bool сыграло бы правило "все, что не 0, то true", я тут не вижу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Результат оператора ! имеет тип bool, неявного преобразования его операнда к int, в процессе обратного преобразования от которого к bool сыграло бы правило "все, что не 0, то true", я тут не вижу

Даже не так. Результат оператора ! - это 0 или 1 по определению. Поэтому ! и !!! - это одно и то же. Другое дело, что компилятор вправе рассчитывать, что переменная типа bool содержит 0 или 1, отсюда и оптимизация (XOR). Если это условие нарушено (хотя бы из-за того, что переменная не инициализирована), то кодер сам дурак.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то кодер сам дурак.

Будьте осторожнее с выражениями! Речь здесь идёт не о том, кто дурак, а кто умный. Вопрос был задан вполне конкретно. И право кодера не знать на него ответ. Собственно говоря, для этого этот вопрос и задавался.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да не обижайтесь так. Это я фигурально выразился, так сказать. К тому же никого конкретного не имел в виду и фамилий не называл :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...