Initialising a BOOL array to TRUE ??

S

Simon L

BOOL bMyarray[1000];
memset(bMyArray , 0xFF, sizeof(BOOL) * 1000);

clean & quick until someone else's code found I was returning -1 to
mean true

Because my BOOL is 4 bytes long, TRUE in memory works out as 01 00 00
00 which is a right pain.

Doing it in a for loop is 10 x slower btw.

Bit of a numpty question this, is there another way?

TIA
 
I

Ian Collins

Simon said:
BOOL bMyarray[1000];
memset(bMyArray , 0xFF, sizeof(BOOL) * 1000);

clean & quick until someone else's code found I was returning -1 to
mean true

Because my BOOL is 4 bytes long, TRUE in memory works out as 01 00 00
00 which is a right pain.
Why not use bool?
 
P

Pascal J. Bourguignon

Simon L said:
BOOL bMyarray[1000];
memset(bMyArray , 0xFF, sizeof(BOOL) * 1000);

clean & quick until someone else's code found I was returning -1 to
mean true

Because my BOOL is 4 bytes long, TRUE in memory works out as 01 00 00
00 which is a right pain.

Doing it in a for loop is 10 x slower btw.

Bit of a numpty question this, is there another way?

If you have a lot of booleans, it may be worthwhile to store them as
bits. Using less memory, more of the vector will stay in L1-cache, so
accessing them will be faster (even considering the bit
packing/unpacking):


#include <iostream>
#include <limits.h>
typedef int bit; // one bit, 0 or 1
typedef int word; // some bits
#ifndef WORD_BIT
#define WORD_BIT (sizeof(word)*CHAR_BIT)
#endif

class bit_vector {
protected:
unsigned int dimension;
word* words;
public:
bit_vector(unsigned int dimension){
this->dimension=dimension;
this->words=new word[(this->dimension+WORD_BIT-1)/WORD_BIT];
}
virtual ~bit_vector(){
delete [] this->words;
}

inline bit operator[](unsigned int index){
return((index<this->dimension)
?(1&(this->words[index/WORD_BIT]>>(index%WORD_BIT)))
:0); }

inline bit set(unsigned int index,bit value){
if(index<this->dimension){
if(value==0){
this->words[index/WORD_BIT]&=(~(1<<(index%WORD_BIT)));
}else{
this->words[index/WORD_BIT]|=(1<<(index%WORD_BIT)); }}
return(value); }

// so now filling the vector will be 256 times faster:

void fill(bit value){
word filler=(value==0)?(0):(~0);
for(unsigned int i=0;i<(this->dimension+WORD_BIT-1)/WORD_BIT;i++){ this->words=filler; }}

};

using namespace std;

int main(void){
bit_vector v(1000);
v.fill(1);
cout<<v[0]<<", "<<v[999]<<endl;
v.fill(0);
cout<<v[0]<<", "<<v[999]<<endl;
v.set(0,1);
cout<<v[0]<<", "<<v[999]<<endl;
v.set(999,1);
cout<<v[0]<<", "<<v[999]<<endl;
return(0);
}
 
B

Ben Bacarisse

It is best not to quote sigs.
I'm working in C (oops, wrong group..)

C also has bool.

By the way, if you want to save some pride, it is likely that the code
that found out you were using -1 for true is flawed. -1 is a
perfectly good true value (in both C an C++) it just does not compare
== to true. Good code should not test booleans for equality simply
because, historically, anything not zero is true.
 
J

Jerry Coffin

[ ... ]
If you have a lot of booleans, it may be worthwhile to store them as
bits. Using less memory, more of the vector will stay in L1-cache, so
accessing them will be faster (even considering the bit
packing/unpacking):

[ code elided ]

While your advice is certainly reasonable, I'd note that yet _another_
bit-vector implementation is about the last thing C++ needs. The
standard requires that std::vector<bool> be specialized to store bools
as a single bit apiece. The standard also includes std::bitset for
storing, manipulating, etc., sequences of bits. In the case of bitset,
the size of the set is a template argument, so it must be a compile-time
constant.
 
P

Pascal J. Bourguignon

Jerry Coffin said:
[ ... ]
If you have a lot of booleans, it may be worthwhile to store them as
bits. Using less memory, more of the vector will stay in L1-cache, so
accessing them will be faster (even considering the bit
packing/unpacking):

[ code elided ]

While your advice is certainly reasonable, I'd note that yet _another_
bit-vector implementation is about the last thing C++ needs. The
standard requires that std::vector<bool> be specialized to store bools
as a single bit apiece. The standard also includes std::bitset for
storing, manipulating, etc., sequences of bits. In the case of bitset,
the size of the set is a template argument, so it must be a compile-time
constant.

Ah, that's true, I forgot std::vector<bool> was special-cased.
 
J

James Kanze

C also has bool.
By the way, if you want to save some pride, it is likely that
the code that found out you were using -1 for true is flawed.
-1 is a perfectly good true value (in both C an C++) it just
does not compare == to true. Good code should not test
booleans for equality simply because, historically, anything
not zero is true.

I don't know about C, but in C++, a bool can only take on two
legal values, true and false. The implementation can represent
them any way it wants (as long as the convert to 1 and 0), and
anything you do which puts some values other than what the
implementation uses into the variable results in undefined
behavior.

In C++, of course, this isn't a problem: std::fill is typesafe,
and normally should be faster than memset as well.
 
G

Gennaro Prota

Jerry said:
While your advice is certainly reasonable, I'd note that yet _another_
bit-vector implementation is about the last thing C++ needs. The
standard requires that std::vector<bool> be specialized to store bools
as a single bit apiece.

Caution. The standard does *not* require such a representation. It
just allows it.
 
J

Jerry Coffin

Caution. The standard does *not* require such a representation. It
just allows it.

According to section 23.2.5, "To optimize space allocation, a
specialization of vector for bool elements is provided". It's
undoubtedly true that an implementation _could_ be written that would
use multiple bits of storage for each bool, but if such a thing exists,
I've never heard of it.

At least IMO, in comp.std.c++, your comment would be absolutely correct,
but in comp.lang.c++, it's basically wrong.
 
G

Gennaro Prota

Jerry Coffin wrote:
[...]
According to section 23.2.5, "To optimize space allocation, a
specialization of vector for bool elements is provided". It's
undoubtedly true that an implementation _could_ be written that would
use multiple bits of storage for each bool, but if such a thing exists,
I've never heard of it.

I forgot that I had to mention the above sentence, and the fact that I
knew the intent from discussions with LWG members. This was sort of a
movie script, years ago: someone mentioned that the "optimization" was
not mandated and someone else inevitably mentioned 23.2.5; see e.g.

<http://google.com/group/comp.lang.c++.moderated/msg/875831806db06ead>

As you can see from there, too, I agree that the sentence is unclear.
At least IMO, in comp.std.c++, your comment would be absolutely correct,
but in comp.lang.c++, it's basically wrong.

Well, it's either correct or not. It doesn't depend on what newsgroup
you are in :)

In this case, anyhow, it would be an undecidable comment on the basis
of the standard which we happen to resolve from information "under the
counter". (Just to be clear: I don't like this state of fact... a
standard should be clear in itself, and not require a phone call to
any sentence author in order to know the intent... Another argument we
have hit repeatedly in the past :-/).
 
J

Jerry Coffin

gennaro/[email protected] says... said:
Well, it's either correct or not. It doesn't depend on what newsgroup
you are in :)

Not really. comp.std.c++ is about what the standard requires, and from
that viewpoint you're right.

comp.lang.c++ is about _using_ C++; when _every_ compiler extant works
in a particular way, that's how the language works as far as actual use
goes, even if (theoretically) something else could exist.

This is more or less the same as using an exported template, but in the
reverse direction -- from a viewpoint of the standard, there's no
question that it's acceptable. For real use, it's completely
unacceptable for nearly everybody (i.e. anybody who has to use any
compiler other than Comeau).
 
B

Ben Bacarisse

James Kanze said:
I don't know about C, but in C++, a bool can only take on two
legal values, true and false.

Ditto in C. That is why I said "historically" and "booleans" (rather
than bools). It is safe (but odd) in C99 to test a bool == true.

I was addressing the OP's use of -1 in a BOOL (some MS type, most
likely) which is defensible on the grounds that without a proper bool
type, testing for equality is bad style. This was not clear, since I
started with "C also has bool". I should maybe have continued
"However, without it...".

In C++, of course, this isn't a problem: std::fill is typesafe,
and normally should be faster than memset as well.

I note that the OP really wants C, and if they post in comp.lang.c
I am sure they'll get the rather less neat C idiom!
 
J

James Kanze

Ditto in C. That is why I said "historically" and "booleans"
(rather than bools). It is safe (but odd) in C99 to test a
bool == true.

I know that C99 added _Bool, but I'm not too sure about its
semantics. If I understand the C++ standard correctly, it
guarantees that, given:

bool b ;
int i ;

, i = b will result in i having the value of 0 or 1, and b = i
will result in b having the value false if i == 0, and true
otherwise. I'm not sure, but I don't think it makes any
guarantees with regards to what the actual bits in b contain. I
think an implementation could ue 43 for true, and 7 for false,
as long as it did the conversions correctly. (Practically,
speaking, of course, no implementation will do this.)

And because C and C++ do define bool differently (i.e. using
different words---the definitions in C99 are not copied from
C++), it's far from sure that C offers the same liberty in this
regard. (At the "correct" usage level, they should behave the
same.)
 
J

James Kanze

[ ... ]
comp.lang.c++ is about _using_ C++; when _every_ compiler
extant works in a particular way, that's how the language
works as far as actual use goes, even if (theoretically)
something else could exist.

To agree with you, but in somewhat different words: the
definition of C++ differs between the groups: in comp.std.c++
(supposing it was still there), C++ means the language defined
by ISO 14882, and nothing else. Here, C++ means what we
generally understand by the language, accross all (or most)
platforms implementing it. (Thus, for example, here, there is
no "export":-(. But there are threads, DLL's and who knows what
all else.)
This is more or less the same as using an exported template,
but in the reverse direction -- from a viewpoint of the
standard, there's no question that it's acceptable. For real
use, it's completely unacceptable for nearly everybody (i.e.
anybody who has to use any compiler other than Comeau).

Exactly. The word "C++" has a different meaning in the two
groups.
 
P

Pascal J. Bourguignon

James Kanze said:
I know that C99 added _Bool, but I'm not too sure about its
semantics. If I understand the C++ standard correctly, it
guarantees that, given:

bool b ;
int i ;

, i = b will result in i having the value of 0 or 1, and b = i
will result in b having the value false if i == 0, and true
otherwise. I'm not sure, but I don't think it makes any
guarantees with regards to what the actual bits in b contain. I
think an implementation could ue 43 for true, and 7 for false,
as long as it did the conversions correctly. (Practically,
speaking, of course, no implementation will do this.)

I'd be not so sure. Depends on the processor. For example, the 680x0
boolean instructions use $ff for true and $00 for false (ST, SF, SEQ,
SNE, etc). A superfast compiler for these processors wouldn't lose
time with a NEG.B needed to get 0 or 1, so you could get 0 or 255 for
false or true. Or, if sign-extended, 0 or -1.

Hence the goodness of defining i=b; to be i=b?1:0;
 
B

Ben Bacarisse

James Kanze said:
I know that C99 added _Bool, but I'm not too sure about its
semantics. If I understand the C++ standard correctly, it
guarantees that, given:

bool b ;
int i ;

, i = b will result in i having the value of 0 or 1, and b = i
will result in b having the value false if i == 0, and true
otherwise.

Yes, and this is true in C also. (Lets assume stdbool.h is included
then we can use "bool".)
I'm not sure, but I don't think it makes any
guarantees with regards to what the actual bits in b contain.

In C, because _Bool is an unsigned integer type, it is composed only
of value bits and padding bits and because its value can be only 0 or
1 we know that there is only one value bit. All the other
sizeof(_Bool)*CHAR_BIT bits are padding.
I
think an implementation could ue 43 for true, and 7 for false,
as long as it did the conversions correctly. (Practically,
speaking, of course, no implementation will do this.)

A C implementation could use those values, but I am not entirely sure
a C++ implementation could. C could not, however, use 15 for false
and 7 for true since one of the bits must be a value bit set 1 to
represent 1 and 0 to represent 0. For an 8-bit bool there are two
eligible value bits in your 43/7 example.
And because C and C++ do define bool differently (i.e. using
different words---the definitions in C99 are not copied from
C++), it's far from sure that C offers the same liberty in this
regard. (At the "correct" usage level, they should behave the
same.)

My reading of C++ is that there is slightly /less/ freedom in the
representation used for bool. bool is an integer type in C++ (but it
is not guaranteed to be unsigned as in C) and integral types must use
a "pure binary representation" using 2's complement, 1's complement or
sign and magnitude. I can't see any permission for padding bits
within a POD of integral type. Of course, all the explicit talk of
conversions in C++ may be intended to say that, while there may be
lots of bits in the value of a bool, you never "see" them because it
always converts to 1 or 0 and always compares to true or false.
 
J

James Kanze

Pascal J. Bourguignon <[email protected]> wrote:

[...]
If you mean to actually code that last statement: don't.

You could argue that implicit conversions hurt readability, and
prefer something more explicit than just "i = b", either an
explicit conversion, or that last statement. I'll admit that
while I would agree with that in theory, I don't often bother in
practice.
 
J

James Kanze

Yes, and this is true in C also. (Lets assume stdbool.h is
included then we can use "bool".)
In C, because _Bool is an unsigned integer type, it is composed only
of value bits and padding bits and because its value can be only 0 or
1 we know that there is only one value bit. All the other
sizeof(_Bool)*CHAR_BIT bits are padding.

Ah, yes. That would cover it.
A C implementation could use those values, but I am not
entirely sure a C++ implementation could. C could not,
however, use 15 for false and 7 for true since one of the bits
must be a value bit set 1 to represent 1 and 0 to represent 0.
For an 8-bit bool there are two eligible value bits in your
43/7 example.
My reading of C++ is that there is slightly /less/ freedom in
the representation used for bool. bool is an integer type in
C++ (but it is not guaranteed to be unsigned as in C) and
integral types must use a "pure binary representation" using
2's complement, 1's complement or sign and magnitude. I can't
see any permission for padding bits within a POD of integral
type.

The first paragraph of §3.9.1: "For character types, all bits of
the object representation participate in the value
representation. For unsigned character types, all possible bit
patterns of the value representation represent numbers. These
requirements do not hold for other types." Note that last
sentence: for other types (including bool), it is not required
that all bits participate in the value representation. Trapping
representations are definitly allowed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top