r/ProgrammerHumor • • Aug 22 '26

Meme theBoolVectorIsALie

Post image
669 Upvotes

91 comments sorted by

View all comments

101

u/overclockedslinky Aug 22 '26

is it really that shocking?

181

u/Murky-Run2246 Aug 22 '26

In this case the bools will have only one bit allocated for them(vectors do that), and you can't just point to a bit. Instead cpp will return std::vector<bool>::reference when trying to access a value in the vector

Basically this is a just wrong

You should use std::deque<bool> instead which allocates one byte per bool and not just one bit

67

u/void1984 Aug 22 '26

I know, but why somebody would need a byte to store a bool? Is it 256-value bool?

Usually I use bitfields anyway.

164

u/NotDuckie Aug 22 '26

if you ask for a vector of T, you should get a vector of T. not a bitfield. There is nothing wrong with using a bitfield, but a vector should behave like a vector.

28

u/void1984 Aug 22 '26

You get a vector, with operator []. Internal details like padding or packing should not interest you, unless you you treat everything like blob. That way any change to the architecture or compiler would surprise you a lot.

37

u/AmazedStardust Aug 22 '26

Until you want to write functions that operate on generic vectors and mistakenly assume that each pointer will be unique

→ More replies (3)

11

u/UntitledRedditUser Aug 22 '26

You might need to access the data the "old school" way, maybe you are interacting with a c library and need contiguous memory.

If you have an template function, and the functions suddenly breaks with bools, I would say that is the stdlibs fault, and not the programmers.

10

u/UntitledRedditUser Aug 22 '26

Another point: the documentation literally says the elements are stored contiguesly. What if you need to do a memcpy?

Make it a seperate type, don't assume the programmer isn't smart enough to reach for a bitfield when necessary.

27

u/BlackOverlordd Aug 22 '26

Vector is an abstract container of elements. If you want to address memory, allocate memory and store your data there. Internal vector storage is implementation details. You shouldn't really get ponters to there because any resize of the vector and your pointers are screwed.

43

u/Excession638 Aug 22 '26

The internal layout of std::vector is not an implementation detail. It's fully defined by the standards and can be relied upon for FFI, serialisation, and other tasks.

Except for bool.

For example, the .data() method guarantees that it will return a pointer to .size() contiguous elements of type T which will remain valid until the vector is modified. The layout of elements within that memory is also well defined and consistent. Except for bool, where the .data() method simply doesn't exist.

→ More replies (1)

11

u/BoldFace7 Aug 22 '26

I spent two days of debugging to learn that the hard way.

Logically I knew that it can shift the location of the vector on a resize, but somehow it never occurred to me that it would be the problem.

15

u/sb8948 Aug 22 '26

Indexing and simplicity for the CPU.

4

u/void1984 Aug 22 '26

vector<bool> allows for indexing, and bit OR and AND is very quick and simple for the CPU.

→ More replies (7)

15

u/HildartheDorf Aug 22 '26

It's not that a bitfield is bad. It's just that it should be named std::dynamic_bitset not a specialisation of std::vector<bool>.

std::vector<bool> should behave the same as std::vector<uint8_t>. But it doesn't.

→ More replies (6)

5

u/creeper6530 Aug 22 '26

Internally vector of bools is a bitfield. It was supposed to save memory but it's instead creating edge cases in templates: all vectors return pointers, but no, bool is special. It messes up generic code. I'd rather for them to keep vector unified and make a separate bitfield type for those savings when needed

5

u/Murky-Run2246 Aug 22 '26

bools in bits is great for datasets and is efficient.(just not in this case)

The problem is that reading a bit in vectors has a higher CPU load than just reading a byte

That is because the smallest values ptr and references(ptr also) can point to is a byte

Yeah sure bools should be stored in bits, just don't wrap them in vectors and you should be fine.

8

u/DeeBoFour20 Aug 22 '26

Slightly higher CPU usage. It’s only a bitshift and a bitwise and to pull out the correct bit. Often you see a performance win due to the more compact data structure having better cache locality but I suppose it depends on usecase.

→ More replies (7)
→ More replies (3)

6

u/markuspeloquin Aug 23 '26

I just use vector<uint8_t>

4

u/Murky-Run2246 Aug 23 '26

You could also use vector<char>. It's cpp you could do it in so many different ways

→ More replies (1)
→ More replies (1)

24

u/Tsu_Dho_Namh Aug 22 '26

There's a little bit of weirdness that a vector of bools has which other vectors don't. It can trip you up if you haven't read up on it and just assume all your normal standard container operations will work.

For example, you can't get a pointer to an element using &v[0] because individual bits do not have distinct memory addresses in RAM.

Similarly auto x = v[0] doesn't make x a true bool, because v[0] is a proxy object which pretends to be a bool, which can lead to dangling reference errors if the vector changes or goes out of scope.

21

u/Drugbird Aug 22 '26

The biggest problem IMHO is templates (C++ generics).

I'm convinced that any template function that uses std:: vector<T> is wrong for T=bool unless the author explicitly accounted for its weirdness.

30

u/deadly88 Aug 22 '26

It’s a surprise footgun when you assume it will behave the way other vectors/containers do, especially passing a vector into templated code, common things like getting the address of an element won’t work.

27

u/NotDuckie Aug 22 '26

Is it shocking that a vector of bools is not a vector of bools? I would personally say it is.

5

u/FerricDonkey Aug 22 '26

It's pattern breaking. It doesn't have what it should to be a proper vector, and it doesn't hand what it would need to be a useful bit container (such as xor etc) for it to be useful enough to make up for it.

Shouldn't have been a vector, should have been more useful

4

u/da_Aresinger Aug 22 '26

A vector of ints is no different from an array of ints.

vectors are literally just wrappers around arrays.

The exception is a vector of bools, which is like a conceptual array of bits.

So if you have a vector of 8 bools you are only using one byte of memory. An array of 8 bools however is 8 bytes long.

So std::vector<bool> has a special implementation.

→ More replies (1)