6

According to the answers in this question, std::vector<bool> implements "special" logic (to allow each boolean value to be stored in a single bit, rather than taking up an entire byte), and because of that, it doesn't quite fulfil the requirements of an STL container and its use is therefore discouraged. However, the "special" logic is retained for backward-compatibility reasons.

My question is, if the C++ implementers were to throw out the "special" logic and turn std::vector<bool> into just another specialization of the std::vector template, what backwards compatibility problems would that cause? i.e. is there some special behavior that old software might be relying on that requires the bit-packing implementation to be retained? (the only thing I can think of is that some old software in a RAM-constrained environment might be relying on the eightfold-reduction in memory usage in order to function, but that seems like a relatively minor concern in most contexts)

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • "but that seems like a relatively minor concern in most contexts" Approximately the only users of `std::vector` are those who would be concerned by this. – Caleth Nov 03 '21 at 15:21
  • 1
    @Caleth my suspicion is that the people using `std::vector` in RAM-constrained environments are very unlikely to update to a new version of C++ anyway, as they are running on very old software and hardware and probably don't wish to change/break anything. The other users of `std::vector` would be all the people who *want to* use it but are currently told not to do so. – Jeremy Friesner Nov 03 '21 at 15:23
  • Not just RAM constrained, but also memory-bandwidth constrained. The people who want to use it but don't aren't the users who would suffer breakage, because by definition they aren't using it. – Caleth Nov 03 '21 at 15:25
  • The problem they suffer is when they try to use the current implementation and run into problems, and end up on Stackoverflow trying to figure out why things aren't working, only to find out they've stepped on an old rake that has never been cleaned up :) – Jeremy Friesner Nov 03 '21 at 15:32
  • ABI breaking changes :-( – Jarod42 Nov 03 '21 at 15:51
  • 1
    Also consider this answer https://stackoverflow.com/a/35695593 – Aykhan Hagverdili Nov 03 '21 at 17:31

2 Answers2

3

I believe the crux of the problem is DLL compatibility.

If they change the memory of any standard classes, then that class can't be passed across a DLL boundary, because we don't know which memory format the DLL was expecting, unless we know for certain that they were compiled with the same C++ version.

This is also why Windows APIs take pointers to structs, and the first member of the struct is the size. This allows them to append members to the struct in new versions of Windows, but older applications will continue to be able to call the methods.

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • 2
    I would think that DLL compatibility would be an issue only if you were trying to link to C++ DLLs that were compiled to target different versions of the C++ language, but AFAIK that's already unsupported(?) – Jeremy Friesner Nov 03 '21 at 15:52
  • 2
    @JeremyFriesner usually newer versions of the standard library are binary-compatible with older versions, so you don't have to recompile the whole world anew. – Aykhan Hagverdili Nov 03 '21 at 17:00
  • 1
    @JeremyFriesner Windows didn't support it for a long time, but now they kinda sorta do. Linux has supported it, which is why the C++11 string layout change was such a big deal. – Mooing Duck Nov 03 '21 at 18:28
3

Firstly, that would be an ABI break. A major reason why changing anything from the standard library is difficult.

Secondly, anything using flip would break:

#include <vector>

int main() {
  std::vector<bool> vec { true };
  vec[0].flip(); // can't be done with regular bool
}

Thirdly, there would probably be other problems due to overload resolution someone probably relies on.


Side note: You can always use boost::container::vector instead, which is not specialized for bool.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93