Proposal new type "flags"

Steve Horne stephenwantshornenospam100 at aol.com
Wed Jan 10 09:39:04 PST 2007


On Wed, 10 Jan 2007 00:39:03 -0500, "Jarrett Billingsley"
<kb3ctd2 at yahoo.com> wrote:

>"Rueschi" <rueschi at GIquadrat.de> wrote in message 
>news:eo1nft$1831$1 at digitaldaemon.com...

>> many functions may be controlled by some flags that are combined
>> in an uint value. However, this is not type safe. You can unintentionally
>> provide/combine flags that are not intended for that function.
>> The solution would be a "flags" data type, similar to enums:
>
>I have wanted something like this so, so many times.  Enums make you 
>expliitly number the flags and then you have to use a plain uint param to 
>accept flags.. it's just a pain.  Something like this would be fantastic. 

I'm pretty sceptical about this.

The thing is that I tend to want some things that aren't single-bit
flags - some things that use several bits. Or at least the ability to
test several flags in one go. To do that, you need masks to isolate
each group of bits as well as the various values for each group.
Having a flags feature that could cope with generalisations like that
would probably be more complex than its worth, and if it can't handle
these generalisations, to me it's worse than worthless. Yes, worse,
since you'd end up wasting time converting other peoples flag sets to
enumerates with explicit values when the requirements change and you
need those generalisations.

Another common requirement is to pack a couple of flags into the most
significant bits of an integer that doesn't need all its bits. This
means having flag values that start high and count downward, and
having a mask to extract the integer itself as well. For example, in a
multiway tree data structure (such as a B+ tree database index) I
might pack leaf-node and root-node flags into the high two bits of a
node-size field.

A simple one-bit-per-flag counting upwards from bit zero is, for me, a
very rare exceptional case. The only cases where I remember it
happening are in artificial teaching examples back in college. The
nearest real-world programming match I have is a C++
set-of-unsigned-integers class that I use a lot which packs bitsets
into an underlying vector of integers, but the flags are associated
with integer values (normally some kind of UID), not identifier names.


Also, packing bits into an integer tends to be slower than just using
a boolean type, and since the saving in memory is usually small
(saving a couple of bytes here and there is pointless on machines with
megabytes, let alone gigabytes, of memory) there's no gain to pay for
the extra complexity. You should only do it if you have a specific
good reason.

The main use of packed bit flags is in file formats and communications
protocols, and in that case you probably want to specify explicit flag
values anyway - either because you are working to someone elses file
format, or because you don't want flag values to change accidentally
between versions just because someone added a new flag in the wrong
place.


There's a 'set' feature in Pascal that essentially does this, but one
thing I remember quite clearly from back when I used Turbo Pascal is
that I always handled my flag sets explicitly by packing them into
integers myself. Using sets was simply not practical for real-world
programs.

That said, I quite regularly use lists of strings as flag sets in
Python. It's easy, so if I don't care about efficiency, why not? The
point being that different issues affect different projects, and
perhaps this flags feature really is the right tool for certain jobs.

-- 
Remove 'wants' and 'nospam' from e-mail.



More information about the Digitalmars-d mailing list