2014-11-30 3 views
-2

Я работаю над программой, где мне нужна переменная с тремя состояниями, нетронутыми (неинициализированными), истинными и ложными, поэтому логический выбор будет для этого оптимальным выбором. Но у меня возникают некоторые проблемы при определении того, нет ли bool нетронутым. Я быстро обнаружил, что bool по умолчанию имеет значение 204 или 205, но как конкретно вы можете сказать? Я сделал несколько тестов на этом, и я заметил, что в одной из моих программ он был последовательно 204, а в другом - 205.Неинициализированное логическое значение в C++

Я не уверен, что определяет значение, и или нет, это зависит от программы ИЛИ на основе разработки и используемой операционной системы, но будет ли это значение согласованным во всей программе независимо от операционной системы или устройства? Как и в, она будет работать что-то вроде

//for some reason the default is only 204 or 205 when in an array 
    bool asdf[1]; 
    const bool UNDEFINED_BOOL = asdf[0]; 

и чем с использованием значения UNDEFINED_BOOL через вне программы в качестве сравнения, чтобы увидеть, если BOOL (в массиве) не определено? он работает на моем устройстве, но будет ли он работать на всех устройствах и во всех операционных системах? Является ли это чем-то согласованным на всех C++? и есть ли другой способ узнать, какой будет ценность неопределенного bool, или это то, что вы не можете определить без примера?

EDIT: когда что-то устанавливается истинным или ложным в случае моей программы, будет NEVER быть причиной, чтобы установить его в неинициализированный, так что это не то, что я должен беспокоиться о

+1

Неинициализированная нестатическая и не-потоковая локальная переменная неопределенна, все остальные неинициализированные переменные инициализируются нулем. Не читайте неопределенные переменные, вы просто получите скорбное живот. – Deduplicator

+1

http://thedailywtf.com/articles/What_Is_Truth_0x3f_ – Deduplicator

+0

@Deduplicator, но если вы можете определить согласованное значение неинициализированного логического значения, и у вас есть список из 2,5 миллионов, где вам нужны только три состояния, не лучший ли он выбор использовать булевую, а не более крупную структуру данных? –

ответ

7

A bool имеет только 2 состояния: true или false. Таким образом, это был бы ужасный выбор, когда вам нужно 3 состояния (true, false, uninitialized). Для этого я бы рекомендовал enum.

Я думаю, вы просто не понимаете, что означает «неинициализированный». Это не состояние булева типа. Это буквально означает неинициализированную переменную. Использование этого значения - неопределенное поведение.


Edit:

Почему вы даже с учетом bool, когда вы хотите, чтобы обнаружить более 2 состояния? Вы просто выбрали неправильный тип данных. Если вы хотите, чтобы наименьший тип данных представлял ваши 3 значения, выберите наименьший тип, который может поддерживать не менее 3 значений. Это будет либо uint8_t, или, может быть, вы можете использовать битовое поле, если вы пытаетесь, чтобы упаковать это в структуре:

enum MyTristate : uint8_t 
{ 
    False = 0, 
    True = 1, 
    Undefined = 2 
}; 


struct MyStruct 
{ 
    ... 
    MyTristate someField : 2;// you only need 2 bits to support MyTristate. 
    ... 
}; 

Позвольте мне также добавить: Вы чувствуете, что вы нашли способ использовать bool к обнаруживают более двух типов данных. Нет причин пытаться использовать что-либо. Также кажется, что у вас под ложным впечатлением, что bool является наименьшим типом данных; это не. Точный размер определяется реализацией, но вы не найдете никакой реализации, которая хранит его меньше, чем uint8_t.

Ваш комментарий ниже,

... если я могу определить значение неинициализированного булево (который, кажется, всегда быть либо 204 или 205)

Вы не можете; это иллюзия. И нет никакой пользы знать эти ценности в любом случае. Они бессмысленны.bool либо true, либо false, период. Если вы нашли какой-то способ определить другие значения, чем это, вы работаете за пределами спецификации и в стране неопределенного поведения. Компилятор работает строго в рамках спецификации C++, чтобы позволить такие вещи, как оптимизация. В тот момент, когда вы полагаетесь на что-то из спецификации, вы попадаете в мир обиды.

Вы меняете платформы, ваш код незаметно ломается.

Вы изменяете настройки оптимизации, ваш код незаметно ломается.

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

Невозможно обобщить, что такое неинициализированное значение. Вы обнаружили, что в вашем случае это может быть 204 или 205. Как вы можете знать, что ваш компилятор также не будет генерировать 206? Вы не можете.

Аналогично, как вы узнаете, что двоичное представление вашего компилятора для true не 204? Опять же, вы не можете.

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

+0

Использование не UB. По крайней мере, не всегда, при любых обстоятельствах. (Но языковая адвокация этих углов - действительно плохая идея, так что неважно.) – Deduplicator

+0

Я знаю это, но в моем случае, если я могу определить значение неинициализированного булева (который, кажется, всегда будет 204 или 205), он быть лучшим выбором, поскольку вы можете воспользоваться небольшим размером структуры данных, а также воспользоваться дополнительным состоянием «неинициализированным», которое дает логическое значение. У меня есть список из 2,5 млн., Поэтому для меня важно максимально использовать наименьшую структуру данных. –

+0

Ответ в редакции – tenfour

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