2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3, 4  След.
 
 true(204) в C++ что за зверь?
Сообщение09.11.2022, 21:22 
Аватара пользователя


05/06/08
477
Алгоритм работает с BigInteger, поэтому прямое сравнение не проходит, пришлось написать простенькую функцию, сравнивающую два дробных числа:
Код:
bool equal(BQ_LTYPE a, BQ_LTYPE b) {

   return a.ch == b.ch && a.z == b.z;
}

Функция используется в следующем месте кода:

Код:
bool equ_x = equal(rct_fr[fr_i].qx, rct_fl[fl_i].qx);
bool equ_y = equal(rct_fr[fr_i].qy, rct_fl[fl_i].qy);

Первая строка сравнивает 1/6 c 1/6 и правильно выдает true.
Вторая строка сравнивает 1/5 c 1/5 и вроде бы правильно выдает true. Но в скобке дебагер дает некую цифру (204).
Самое поразительное, что оператор
Код:
if([b]true [/b]&& [b]true(204)[/b]) = false;

Это какая-то загадка, так как 204 - если это число, по сути тоже true.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение09.11.2022, 21:59 


31/08/22
183
В плюсах любое положительное число равно true.

А то, что такой if выдает false действительно странно.
Может приведете листинг программы предшествующий этому if... желательно со значениями в переменных (а то пока Вы это будете делать уже и ошибку отловите :D )

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 04:02 
Аватара пользователя


28/10/21
100
MGM в сообщении #1569536 писал(а):
Вторая строка сравнивает 1/5 c 1/5 и вроде бы правильно выдает true. Но в скобке дебагер дает некую цифру (204).


В какой "скобке"? Где дебаггер вам это "выдает"? О чем речь?

MGM в сообщении #1569536 писал(а):
Самое поразительное, что оператор
Код:
if([b]true [/b]&& [b]true(204)[/b]) = false;

Это какая-то загадка, так как 204 - если это число, по сути тоже true.


Что означает эта загадочная запись и какое она имеет отношение к С++?

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 05:34 
Аватара пользователя


28/10/21
100
Schrodinger's cat в сообщении #1569539 писал(а):
В плюсах любое положительное число равно true.


??? В таком буквальном виде это утверждение неверно. Если сравнивать true с целым значением, то true будет преобразовано к значению 1. А 1 не равно 204. Поэтому условие true == 204 всегда гарантированно ложно.

Я примерно понимаю, что вы хотели сказать - с точностью до наоборот: в булевском контексте любое ненулевое целочисленное значение приводится к true. Однако как это относится к теме - не ясно.

-- 09.11.2022, 18:44 --

MGM в сообщении #1569536 писал(а):
Но в скобке дебагер дает некую цифру (204).


Вы нас скорее всего обманываете. Ваше булевское значение не имеет никакого отношения к тем переменным, которые вы привели выше. Значение 204 в шестнадцатеричном виде - это 0xCC. Это подозрительно похоже на какой-то дебажный заполнитель для неинициализированной памяти. То есть вы смотрите на неинициализированную переменную типа bool, которая содержит "мусорное" значение.

MGM в сообщении #1569536 писал(а):
Самое поразительное, что оператор
Код:
if([b]true [/b]&& [b]true(204)[/b]) = false;

Это какая-то загадка, так как 204 - если это число, по сути тоже true.


Нет, нет, нет, ни в коем случае. 204 в переменной типа bool - это не true.

Обращение к "мусорной" булевской переменной порождает неопределенное поведение. На практике, если ее физическое представление не совпадает с корректным представлением true или false на вашей платформе, то такая булевская переменная может вести себя и как "ни true, ни false", так и как "и true, и false одновременно". Этот "феномен" очень часто встречается на практике и удивленными вопросами на эту тему забит весь инет. Не пытайтесь работать с неинициализированными переменными.

На вашей платформе (как и на большинстве платформ) false скорее всего физически представляется как байт 0x00, а true - как байт 0x01. Это значит, что 204 в bool будет вести себя непредсказуемым образом.

Вот вам небольшая программка навскидку

Код:
#include <iostream>
#include <cstring>

bool return_bad_bool() __attribute__((noinline));

bool return_bad_bool()
{
  bool b;
  std::memset(&b, 204, 1);
  return b;
}

int main()
{
  bool b = return_bad_bool();
  if (b)
    std::cout << "True!" << std::endl;
  if (!b)
    std::cout << "False!" << std::endl;
}


При компиляции GCC без оптимизаций эта программа выдает одновременно "True! False!" http://coliru.stacked-crooked.com/a/ded1d2461a7915f2
При компиляции GCC c -O3 эта программа выдает "True!" http://coliru.stacked-crooked.com/a/e8ff36833396d507
При компиляции Clang она всегда выдает "False!" http://coliru.stacked-crooked.com/a/cc113189bb73726c

Посмотрев на сгенерированный ассемблерный код, вы сможете понять, почему так происходит. Но с точки зрения языка это просто неопределенное поведение.

Вот именно это явление вы и наблюдаете в вашем if, когда пытаетесь пихать в него "мусорный" bool.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 09:03 


31/08/22
183
TheRuinedMap в сообщении #1569577 писал(а):
Поэтому условие true == 204 всегда гарантированно ложно.

Согласен, но там другое условие. Там И а не Равно. Математика булева а не целочисленная.
Наоборот тоже можно изголяться бул использовать в целочисленной математике. Понятно что в нормальных программах так лучше не делать.
Целочисленные значения должны преобразовываться в бул.

Код:
int main()
{
    int t = 204;
    if(true && t)
        cout<<"True";

    return 0;
}
Выод:
True


Тоже подозреваю что у ТС что то с недоинициализацией, отсюда и неопределенное поведение.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 17:08 
Аватара пользователя


05/06/08
477
Мне сложно как-то вразумительно объяснить.
Однако подобный вопрос был в англоязычном форуме и с моей точки зрения разрешился не по причине выясненного бага, а в следствие внесения дополнительного кода.
Цитата:
have an object called Symbol which represents a variable. Symbol has the Boolean attribute used which is initialized as false. This condition is changed to true in the event that it is called upon to solve a function to show that it was used. For some reason when Symbol is unused and used is never changed to true it returns the value 204 instead of false

По сути у вопрошающего все в порядке, так как компилятор или код, реально трактует the value 204 as( а не instead of, как чел с вопросом) false.
Еще раз, в строках дебага MS VS2019 две переменные выглядят так
Код:
equ_x   true      bool
equ_y   true (204)   bool

в блок { int a = 0; .........;}
В коде
Код:
[b]if(equ_x && equ_y){ int a = 0;
.........;}[/b]

не попадает.
Но это явно не ашибка алгоритма, а какой-то сдой то ли компилятора, то ли сам не знаю чего.
Так как сравниваемые переменные rct_fr[fr_i].qx rct_fl[fl_i].qx и rct_fr[fr_i].qy rct_fl[fl_i].qy
в
Код:
bool equ_x = equal(rct_fr[fr_i].qx, rct_fl[fl_i].qx);
   
bool equ_y = equal(rct_fr[fr_i].qy, rct_fl[fl_i].qy);


равны согласно тому же дебагеру, более того, они даже не BigInteger. A просто 1/5 и 1/6;

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 17:16 
Заслуженный участник
Аватара пользователя


16/07/14
9152
Цюрих
Покажите более содержательный кусок кода, и без bb тегов. Что такое true(204) - непонятно, это не скомпилируется.
bool в дебагере может показываться как угодно, стандарт ничего про битовое представление true не требует.
(при всей моей нелюбви к MSVS, я довольно сильно уверен, что ошибка в коде, а не в компиляторе)

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 17:33 


14/01/11
3040
Явно неинициализированная переменная. Любое ненулевое число при приведении его к булеву типу даст true, но я не уверен, что может получиться, когда оно участвует в булевой операции. Может, там через побитовые операции над числами всё реализовано. :-) В таком гипотетическом случае побитовое "и" чисел $204$ и $1$ (стандартное значение, соответствующее true) даст, разумеется, $0$. Постарайтесь всё же разобраться, откуда там у вас это $204$ взялось, выведите, например, отдельно значения
Код:
(a.ch == b.ch)
и
Код:
(a.z == b.z)
для этого случая.
Можно ещё добавить, что $204$ aka
Код:
0xCC
подозрительно напоминает один из паттернов заполнения неинициализированной памяти компиляторами Microsoft.
https://stackoverflow.com/questions/370195/when-and-why-will-a-compiler-initialise-memory-to-0xcd-0xdd-etc-on-malloc-fre

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 17:36 
Заслуженный участник
Аватара пользователя


16/07/14
9152
Цюрих
Sender в сообщении #1569639 писал(а):
но я не уверен, что может получиться, когда оно участвует в булевой операции
Если там неинциализированная переменная - то что угодно. Например компилятор проверит, что в эту переменную никто точно не мог записать false, и значит ветки, предполагающие, что там false, можно выкинуть. А потом аналогично с true.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 17:48 
Аватара пользователя


05/06/08
477
//////////////////////////////// P S (204) //////////////////////////////////////////
Могила с этим 204.
Купировал сбой просто перкставив местами два строки кода.
Код:
bool equ_x = equal(rct_fr[fr_i].qx, rct_fl[fl_i].qx);
bool equ_y = equal(rct_fr[fr_i].qy, rct_fl[fl_i].qy);

Но это, конечно, не выход.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 18:00 
Аватара пользователя


28/10/21
100
MGM в сообщении #1569636 писал(а):
По сути у вопрошающего все в порядке, так как компилятор или код, реально трактует the value 204 as( а не instead of, как чел с вопросом) false.


Это прекрасно. Почему компилятор так "трактует" такое 204 - я детально объяснил выше. Никаких проблем или вопросов о "трактовке" 204 не существует. Здесь все ясно и компилятор тут совершенно прав.

MGM в сообщении #1569636 писал(а):
Но это явно не ашибка алгоритма, а какой-то сдой то ли компилятора, то ли сам не знаю чего.


Никакого сбоя компилятора в "трактовке" 204 нет. Вопрос тут только в том, откуда взялось это 204 в переменной типа bool. Такого быть не должно.

MGM в сообщении #1569636 писал(а):
Так как сравниваемые переменные rct_fr[fr_i].qx rct_fl[fl_i].qx и rct_fr[fr_i].qy rct_fl[fl_i].qy
в
Код:
bool equ_x = equal(rct_fr[fr_i].qx, rct_fl[fl_i].qx);
bool equ_y = equal(rct_fr[fr_i].qy, rct_fl[fl_i].qy);


равны согласно тому же дебагеру, более того, они даже не BigInteger. A просто 1/5 и 1/6;


Вот это все, скорее всего, совершенно не имеет никакого отношения к делу. Я глубоко сомневаюсь, что значение 204 было порождено вашей функцией equal. Ваша переменная получила свое 204 не отсюда. Либо вы что-то напутали и смотрите на совсем другую переменную (неинициализированную), либо переменная сначала получила нормальное значение, но потом была затерта "мусором" 204 позже, вследствие каких-то посторонних причин.

Не видя остального кода, трудно судить о том, что и где там у вас произошло. У упомянутого вами вопрошающего на "анголоязычном форуме" произошло что-то аналогичное, ибо, как я сказал выше, затирание значения байтом 0xCC - распространенное явление при разнообразных выходах за пределы массива, неаккуратной работе с динамической памятью и т.п.

Приводите более полный код, желательно воспроизводящий проблему. Есть некий шанс, что дело именно в equal, но тогда это должно быть видно из сгенерированного ассемблерного кода.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 18:01 
Заслуженный участник
Аватара пользователя


16/07/14
9152
Цюрих
Вы можете полностью привести фрагмент, из которого вы взяли это 204?

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 18:02 
Аватара пользователя


28/10/21
100
MGM в сообщении #1569641 писал(а):
Могила с этим 204.
Купировал сбой просто перкставив местами два строки кода.
Код:
bool equ_x = equal(rct_fr[fr_i].qx, rct_fl[fl_i].qx);
bool equ_y = equal(rct_fr[fr_i].qy, rct_fl[fl_i].qy);

Но это, конечно, не выход.


Ничего вы не купировали. Вы просто "спугнули" неопределенное поведение, скорее всего временно. Вы просто замели проблему под ковер, и что скорее всего теперь этим 204 затирается какой-то другой байт в какой-то другой переменной.

P.S. Да, вполне возможно что где-то тут зарыт баг компилятора, но не имея возможности воспроизвести проблему, судить о чем-то трудно.

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 18:07 
Заслуженный участник
Аватара пользователя


16/07/14
9152
Цюрих
TheRuinedMap в сообщении #1569642 писал(а):
Вот это все, скорее всего, совершенно не имеет никакого отношения к делу. Я глубоко сомневаюсь, что значение 204 было порождено вашей функцией equal.
Ну кстати если в самих qx и qy мусор (и компилятор про это знает), то вполне может быть, черт его знает какие он хитрые оптимизации породит, вплоть до того что решит "ну там либо 0 либо 1, так что можно memcpy из int в bool сделать".

 Профиль  
                  
 
 Re: true(204) в C++ что за зверь?
Сообщение10.11.2022, 18:14 
Аватара пользователя


28/10/21
100
mihaild в сообщении #1569637 писал(а):
Покажите более содержательный кусок кода, и без bb тегов. Что такое true(204) - непонятно, это не скомпилируется.


Речь, очевидно, идет не о коде в программе, а об выводе значения переменной в окне дебаггера

Изображение

mihaild в сообщении #1569637 писал(а):
bool в дебагере может показываться как угодно, стандарт ничего про битовое представление true не требует.


Стандарт - не требует. Стандарт говорит, что оно implementation-defined (как, впрочем, и почти все остальные представления), то есть битовое представление будет требовать конкретная реализация. И, разумеется, показываться валидный bool в уважающем себя дебаггере конкретной реализации будет не "как угодно", а как true или false. А вот true(204) в дебаггере MSVC говорит о проблемах...

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 48 ]  На страницу 1, 2, 3, 4  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group