Преобразование bool к int - значения - страница 2

 
Renat писал (а):

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

Например, я себе никогда не позволяю писать if(var) ... , если var не является чистым bool.
Береженого бог бережет.


Я бы тоже так никогда не писал код, но в эксперте много bool-параметров, и клиенту-заказчику удобно выбирать мышью их комбинации, кликая на true/false, без клавиатуры. Но в тоже время ему нужен перебор вариантов включения этих параметров в оптимизаторе, а bool параметры, к великому сожалению, в оптимизатор "не лезут", не включаются.

Поэтому я меняю "базовую" версию эксперта с true/false bool-параметрами, а с него мне нужно быстро и малозатратно делать копию с 0/1 int-параметрами.
Для этого и завёл этот топик с вопросом.
 
chv:
Как bool может хранить число 1048576, с трудом представляю. Оно внутри хранится как int?
bool не хранит число. Число хранится в переменной типа bool - поименованной ячейке памяти или регистре процессора.
bool - это тип данных, принимающих значение 1 (истина, true, yes) или 0 (ложь, false, no), которыми оперирует булева алгебра. То, как тип bool представлен в машинном коде, определяется аппаратной платформой, языком и компилятором, никак не самой алгеброй.
Реализация этой алгебры у каждого языка своя. В частности, она имеет различия в mq4 и Си.
Очевидно, Print в mq4 производит неявное преобразование типа bool к типу int, то есть функция интерпретирует ячейку памяти, как переменную типа int, и, соответственно, печатает целое число, содержащееся в этой ячейке.
Условный оператор может, как Вы заметили, делать обратное неявное преобразование от int к bool. Тогда любое число, отличное от 0, в том числе 10478576, становится просто булевым true. При этом компилятор делает предупреждение, что такое преобразование имеет место. Ошибки здесь никакой нет.
 

Тут возникает целый букет вопросов. Но все они касаются обратного преобразования.
Что касается исходного поста: нельзя ли просто изменить тип bool на int просто при исходной инициализации переменных?




 
SK. писал (а):

Что касается исходного поста: нельзя ли просто изменить тип bool на int просто при исходной инициализации переменных?

Можно, конечно. О чем в посте, собственно, и говорится. И еще три раза в комментариях (теперь четыре).
Только компилятор выдаст предупреждение, потому что, как заметил Renat, неявное преобразование типов зачастую приводит к неожиданным, точнее, к недокументированным, а значит, негарантированным результатам. То, что в программировании называется undefined behaviour - источник многих труднонаходимых ошибок. Особенно, для неопытных программистов.
В серьезных программных продуктах недокументированные возможности языка и компилятора, как правило, строго настрого запрешены к использованию.
 
Irtron:
chv писал (а):
Как bool может хранить число 1048576, с трудом представляю. Оно внутри хранится как int?
bool не хранит число. Число хранится в переменной типа bool - поименованной ячейке памяти или регистре процессора.
bool - это тип данных, принимающих значение 1 (истина, true, yes) или 0 (ложь, false, no), которыми оперирует булева алгебра. То, как тип bool представлен в машинном коде, определяется аппаратной платформой, языком и компилятором, никак не самой алгеброй.
Реализация этой алгебры у каждого языка своя. В частности, она имеет различия в mq4 и Си.
Очевидно, Print в mq4 производит неявное преобразование типа bool к типу int, то есть функция интерпретирует ячейку памяти, как переменную типа int, и, соответственно, печатает целое число, содержащееся в этой ячейке.
Условный оператор может, как Вы заметили, делать обратное неявное преобразование от int к bool. Тогда любое число, отличное от 0, в том числе 10478576, становится просто булевым true. При этом компилятор делает предупреждение, что такое преобразование имеет место. Ошибки здесь никакой нет.

Я уже писал выше, почему вынужен использовать подобные "трюки" и преобразования - bool переменные не идут в оптимизатор, а надо.
Что касается ошибки, то Renat заметил, что она всё же есть - bool переменные съедают больше памяти и хранят больше значений, чем им реально требуется. bool - это реально бит, он может хранить только два состояния, или значения, кому как нравится: 0 и 1. В один байт, если делать внутреннюю оптимизацию в компиляторе, можно "затолкать" 8 bool переменных. И при использовании битовых сдвигов (<< и >>) можно делать такие вещи и самому.
Поэтому выражение:
bool B = true;
int  I;
I = 1048576;
...
B = I;
Должно при верном хранении bool данных потерять первоначальное значение int переменной I, каким бы оно ни было, и получить в результате своё значение, адекватное преобразованному значению к true или false. Обычно false - это 0, а true или 1, или -1 в разных языках. Но вот значения в 1048576 затем bool переменная выдать не может никак, она его уже не хранит. Вот в этом, собственно, и ошибка в текущей реализации.
 
chv:
Я уже писал выше, почему вынужен использовать подобные "трюки" и преобразования - bool переменные не идут в оптимизатор, а надо.
А я привел пример воркараунда для использования bool в качестве оптимизируемого параметра.

bool переменные съедают больше памяти и хранят больше значений, чем им реально требуется.
Под bool переменные отводится столько памяти, сколько определяется архитектурой аппаратной платфотмы. Хранят переменные одно из двух значений - 0 и не 0, никак не больше.

bool - это реально бит.
bool - это реально тип данных.

он может хранить только два состояния, или значения, кому как нравится: 0 и 1. В один байт, если делать внутреннюю оптимизацию в компиляторе, можно "затолкать" 8 bool переменных. И при использовании битовых сдвигов (<< и >>) можно делать такие вещи и самому.
Можно. Дерзайте.

Должно при верном хранении bool данных потерять первоначальное значение int переменной I, каким бы оно ни было, и получить в результате своё значение, адекватное преобразованному значению к true или false. Обычно false - это 0, а true или 1, или -1 в разных языках. Но вот значения в 1048576 затем bool переменная выдать не может никак, она его уже не хранит. Вот в этом, собственно, и ошибка в текущей реализации.
bool таки теряет первоначальное значение int, потому что bool оперирует другими категориями. Обычно false - это 0, а true это не 0. Остальное зависит от реализации, хотя может быть и стандартизовано в некоторых языках. Если true может быть представлено 1 или -1 в разных языках, что мешает использовать в каком-нибудь языке, например, 1048576 в качестве аппаратного представления true?
bool переменная не выдает значения 1046576, его выдает переменная int, к которой ненулевой bool неявно преобразуется.

Вы путаете категории языка программирования, а именно, типы данных, с представлением этих данных на аппаратном уровне. bool и int - самые простые из этих типов. Double, например, намного хуже. Попробуйте разобраться с битами double, тогда может и с bool вопросов будет меньше. Компилятор как раз и предназначен для того, чтобы перевести эти категории языка в машинный код. Как он это делает, с точки зрения программиста, вообще говоря, прозрачно. Хотя знать полезно. Код получается маленький и быстрый. И ошибок меньше.
 
Мы, конечно, придём в итоге к тому, что внутреннее представление переменных - это дело компании MetaQuotes. Думаю, Renat и его команда сами решат, как им нужно хранить свои типы данных. Хотя я всегда считал, что полезно знать то, что лежит "под капотом" того, что регулярно применяешь. Сейчас очевидно, что bool хранится как int, это видно по коду:
   bool B;
   double I;
   I = 15.9999;
   B = I;
   Print("B = ", B);
   return (0);
На печать выходит:
2006.11.10 20:30:44 2006.11.06 22:00 exp GBPUSD,H1: B = 15
Целая часть выражения.

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

Я прочитал Ваш код, завести две extern переменных (bool, int) и в зависимости от результата IsOptimization() использовать из них одну или другую. Технически это решение безупречно, согласен. Но насчёт удобства его использования. .. Эксперт является полигоном для испытаний и в нём больше сотни таких bool условий. Если их число удвоится ещё и за счёт int двойников, боюсь, человек, его применяющий, может не выдержать морально. .. шутка :) но в каждой шутке... Вы понимаете.

Скажем так, если выражение if (myIntVar) { ... } не будет приносить мне неприятностей с выполнением по поводу преобразования из 0 в false, и из 1 в true, то проще всего делать replace в тексте bool на int в коде двойника-эксперта, и не париться. Мне так кажется.
 
Irtron:

Хранят переменные одно из двух значений - 0 и не 0, никак не больше.
Справедливости ради отмечу, что здесь Вы всё же не правы. Больше. Потому что "не 0" - это не значение, это бесконечное множество значений целых чисел. И число 1048576 было взято мною "от балды, и для красоты", точно также bool переменная хранит и любое другое целое число, что не есть верно. Пусть Renat сам решает, что им с этим делать.

Вот если бы вдруг bool параметры, как типичный enum с перебором конечного множества значений, стали бы перебираться оптимизатором, это было бы доброе чудо от разработчиков.
Хорошая лесть им, не правда ли? :-)
 
chv:
Справедливости ради отмечу, что здесь Вы всё же не правы.
Зачем же смешивать правоту и справедивость? Лучше уж тогда разобраться, что есть правда, а что - истина.

chv:
Больше. Потому что "не 0" - это не значение, это бесконечное множество значений целых чисел.
Для целых чисел - несомненно. Для bool - нет.

Пожалуйста, осмыслите еще раз разницу между типом и машинным представлением типа. По справедливости.
 
Irtron:
SK. писал (а):

Что касается исходного поста: нельзя ли просто изменить тип bool на int просто при исходной инициализации переменных?

Можно, конечно. О чем в посте, собственно, и говорится. И еще три раза в комментариях (теперь четыре).
Только компилятор выдаст предупреждение, потому что, как заметил Renat, неявное преобразование типов зачастую приводит к неожиданным, точнее, к недокументированным, а значит, негарантированным результатам. То, что в программировании называется undefined behaviour - источник многих труднонаходимых ошибок. Особенно, для неопытных программистов.
В серьезных программных продуктах недокументированные возможности языка и компилятора, как правило, строго настрого запрешены к использованию.


Не выдаст.

Насколько я понимаю, проблема возникает только при преобразовании int > bool, а при bool > int не возникает.

true и false представлены в машине соотв. как 1 и 0. Эти целые значения и будут содержанием переменных, котторые в текущей реализации представлены как bool и которые я предложил исходно инициализировать как int. При этом весь остальной текст остаётся без изменений.

В результате кое-где в тексте появятся строки типа int B = true; , но это не должно приводить ни к каким сообщениям ни на этапе компиляции, ни на этапе выполнения.