Data type diversity

Started by
47 comments, last by Calin 1 year, 9 months ago

Isn`t bool redundant? Is it some kind of reminescense of the old days when it took less memory to keep around (arrays of ) bools rather then ints, shorts or something else?

There doesn`t seem to exist any specialized functionality for bool like there is for char for instance ( which is an int/short as well)

A bool is basically a sign that can be easily replaced by an int. A char is a code that is transformed into an alphabet letter within a GUI.

My project`s facebook page is “DreamLand Page”

Advertisement

bool is the elementary data value that can be stored in a computer. A memory address can store 8 bits (ie 8 boolean values). It is also the fundamental notion “true” vs “false” in for example “if” conditions.

How much storage it uses is a different matter, and unrelated to the “bool” notion.

Note that compact storage is still advantageous for processing speed, especially when you have many booleans, eg with BitSet . I write code where you have hundreds of thousands boolean bits. While memory is sufficient no matter how you store that amount, having a L3 cache line with 64*8 booleans versus 64/4 booleans (single bit for single boolean or int32 for a single boolean) make a huge difference in performance.

Why does it matter if it is necessary?

the diversity is the problem as far as I`m concerned. I had the habit of using arrays of bools because the bool is there for a reason. I came to the conclusion that there is no point in using bools other then as single variables for if gate access.

My project`s facebook page is “DreamLand Page”

Calin said:
A bool is basically a sign that can be easily replaced by an int

Syntactically, yes, but type-wise no. If you replaced it with an int, then the type system couldn't enforce the fact that there is only two possible values of a bool and you couldn't have different function overloads or template specializations taking ints and bools.

Calin said:
I had the habit of using arrays of bools because the bool is there for a reason.

This being said, on a practical level, if you find yourself having arrays of them, that's the point when I would start using bitmasks rather than individual bools. The exception being when you have multiple threads and they each talk to a different bool - if they're in a bitmask, it can take more work to prevent them from stomping each other.

Calin said:
the diversity is the problem as far as I`m concerned.

Diversity is the whole point and ultimately beneficial to those that can control it. The more types you have the more control you have over each type and the assumptions you can build into the compilers work or other automated tools.

I could have a handle that's just an int, but if I make a new type (maybe it even just wraps an int) I can both prevent people from making trivial mistakes as well as from doing something malicious. Even if I've got two different systems that need handles, they each get their own type so that you couldn't accidentally interchange them.

--Russell Aasland
--Lead Gameplay Engineer
--Firaxis Games

Oberon_Command said:
template specializations

this seems to be the new horizon for me in programing. Now this is going to sound strange but the problem is my country doesn`t know anything about templars, knights, crusaders etc. so I need permission to use templates (you will probably say there is no connection between templates and templars). Permission granted?

My project`s facebook page is “DreamLand Page”

Calin said:
you will probably say there is no connection between templates and templars

Correct, there is no connection. A template is just a way to write generic code.

The important arguments for bool's existence are the same as for any type-safe mechanism - catching mistakes at compile time. If you know (as you do with bool) that a function should only take 0 (false) or 1 (true) as an argument, you want to make it a compiler error to pass 2 or 3 or 42 or 4234.

fleabay said:
I fear this is going to spawn a large thread of conversation about the nuances of booleans and the bool data type in various languages.

No need to fear, that's basically guaranteed with the question!

Booleans are different from a bool data type. As long as you remember that, there's not much to debate.

Boolean logic -- the stuff from George Boole who received a ton of awards in the 1840s and 50s -- concerns itself only with values of true and false. That logic can be represented by a single bit for determined states, and two bits if you need indeterminate states of true, false, and maybe/unknown.

A bool data type needs to deal with the discrete computing machines we use. This includes recognition of the smallest addressable unit of memory on the hardware which is never a single bit.

Everything that follows from that stems from the difference between Boolean logic and the bool data type.

Calin said:
Isn`t bool redundant?

Yes for storage, no for logic.

It wasn't added to C until C99, nor was it a distinct type in many of the early C++ compilers. It wasn't until the early 1990s that it spread.

Before that, an integral type was always used, it was not mentioned in the C89 standard or earlier.

Unfortunately it was forced because of the logic around inconsistent definitions. False was nearly always 0, but true was variations of !false, 1, -1 (all bits set), 0xff, 0xffff, any non-zero value with no particular bit set, and more. With standardization the compiler writers could enforce rules around it. One example would be the “any non-zero value” definition, a function could return the value 2, which is technically true, but would compare false when compared with a different bool value. That is, result == TRUE is false, because result is the value 2. Similarly, one library's TRUE (0xff) and a different library's TRUE (1) fail the a==b test.

You can do work-arounds, !!a == !!b, and you can even find that in a lot of code such as the Linux kernel that must accept outside data.

Calin said:
There doesn`t seem to exist any specialized functionality for bool like there is for char for instance

There is a bunch of specialized functionality!

The two most critical are conversion rank and the conversion between types.

Bool has conversion rank less than any other standard integer type, including char. This has side effects that it can only expand, it affects how it is passed as a parameter, promotions, and conversions. These are mostly effects that happen behind your back, so you may not have given them much thought.

Non-arithmetic types can be converted to bool, such as pointers, pointers to members, and null pointers (which internally aren't guaranteed to be the integral value zero). These often require additional processing by the compiler. For example, a pointer to a member is usually a pair of two pointers, if either one is non-zero or non-null the result is converted to true.

When a conversion is made away from bool, regardless of the internal storage method (which is implementation defined) the value false must be converted to the integer zero, and the value true must be converted to the integer one. This solves the issue above, like a==b, if they are done as a bool test then they are guaranteed to be the same internal type and therefore consistent. If they're promoted to an integral comparison they MUST be either 0 or 1, they cannot have the other values.

Logical negation ! has a result type of bool, which engages both conversion rank and type rules. Increment and decrement (++ and --) are expressly forbidden to be bool. There are notes around equality and inequality. There are notes around template parameters. And on and on.

This topic is closed to new replies.

Advertisement