4 ms·
Is there a reason some sort of check wasn’t added to pop_back() implementation? Seems like it would be easy to implement and undefined behavior is not somethin
by mr_00ff00 4y ago
Is there a reason some sort of check wasn’t added to pop_back() implementation?
Seems like it would be easy to implement and undefined behavior is not something that backwards compatibility forces you to keep.
- wizofaus 4y agoBecause the basic principle of C/C++ is to not force the coder to have to pay for checks it mightn't need. Which in some contexts makes sense - for application development, probably not.
- fooker 4y agopop_back() is internally just changing a single index. Now, adding a check is adding several other operations, including a conditional branch. This is fairly bad for performance. So the C++ way is that you write the check yourself if your code requires it.
- mike_hock 4y ago.. on a vector of trivial types. If we have to call a non-trivial destructor for the item being removed, the check stops being significant. Then there can't be a pop without a push or some other operation that filled the vector, and that operation necessarily has the checks and branches to allocate more space if necessary. The compiler should also be smart enough to branch forward to the throw so the branch predictor assumes not taken by default, so this is still cheap af. This is "fairly bad" for performance maybe 1% of the time. For the other 99%, you'd make pop_back check and throw and keep the unchecked version as pop_back_fast or something like that. That's what a sane API would look like.
- fooker 4y ago>If we have to call a non-trivial destructor for the item being removed, the check stops being significant. This is a complicated cost model which compilers usually avoid. >The compiler should also be smart enough. It isn't. > That's what a sane API would look like. Awesome, there is nothing stopping you from creating your own functions which add this check.
- mike_hock 4y ago> It isn't. It definitely is. Go try it on godbolt. > Awesome, there is nothing stopping you from creating your own functions which add this check. Thanks for your amazing insight. STL is lacking? Nothing is stopping us from writing our own functions. STL is garbage? Nothing is stopping us from writing our own replacement. The whole language is garbage? Nothing is stopping us from creating a new one from scratch. Really, you've found the solution to everything.
- ynik 4y agopop_back() implementations have checks, but they're opt-in (and how to opt-in is specific to each implementation). This is just how C++ works: performance over safety, safety is semi-possible but requires a bunch of opt-ins. And the parts needed for safe C++ aren't standardized, so good luck if you're using multiple compilers.
- asveikau 4y agoThe standard does not require it. I was thinking just the same as a bunch of you. If I were implementing a container class, I would include this check. Probably some do. It can't be relied on.
- menaerus 4y agoBecause alternative makes it not much better or safer. It could throw an exception when vector is empty (or return an error in whatever other way) - you will catch the exception and then do what, try to pop_back() again or what exactly can you do? You are at very bad odds to continue with the program when such a fundamental issue pops up in your program so I guess you can only terminate the process? There is no generally meaningful way to recover from an error condition like this, which in its nature is a logical mistake in your code. And that's the reason why I think std::vector won't throw an exception but will give you an opt-in to terminate the process through the assert. I think it's not about the performance, although it can be argued, but it's more fundamental code design problem.
- twic 4y ago> or what exactly can you do? Crash. Crashing is a million times better than undefined behaviour, which can and often does include carrying on computing with incorrect data.
- menaerus 4y agoAnd which is what I already mentioned? And something that standard library already can do for you so I'm not sure about the point you're trying to make. Also, aborting the program is not something you can universally apply. For some it works well for others not so much. Most recent example being the rust in the kernel which, well, tries to take this sort of a purist approach, however, real world doesn't work that way.