On Thu, 5 Feb 2026 at 06:17, François Dumont <[email protected]> wrote: > > > On 1/27/26 11:31, Jonathan Wakely wrote: > > On Tue, 27 Jan 2026 at 08:30, Tomasz Kaminski <[email protected]> wrote: > >> > >> > >> On Mon, Jan 26, 2026 at 10:25 PM François Dumont <[email protected]> > >> wrote: > >>> Hi > >>> > >>> libstdc++: [_GLIBCXX_DEBUG] Make constant evaluation compatible > >>> > >>> In a constant evaluation context the _GLIBCXX_DEBUG is working in a > >>> degradated mode where only iterators are keeping a link to their > >>> container, > >>> the container won't have a list of its iterators. > >>> > >>> In std::__debug::vector and std::__debug::inplace_vector remove all > >>> calls to > >>> std::is_constant_evaluated and code associated to it when returning > >>> true. The > >>> same code is now used in both contexts. > >> What are the exact benefits of this change? During constant evaluation we > >> already > >> detect all UB caused by access via invalid or past the end pointers, so > >> most of the > >> cases are detected. > >> > >> As this will have non-trivial impact on compile-times of programs > >> operation on > >> vector at compile time (including c++26) reflection, I would like to see a > >> more concrete > >> cost (how much longer a decently size example using reflection compilers) > >> vs benefits > >> (examples of situations where this new implementation will detect breach > >> of library preconditions, > >> that are not already detected). > > In this new version I've added an example of breach. > > _GLIBCXX_DEBUG mode is already known to be costly and is documented as > having a performance impact. It seems normal to me that it also has some > impact in consteval context.
But usually the extra overhead is useful for finding bugs, but if the bugs are already found during consteval, then it just slows down compilation without finding any more problems. > > I don't know much about the reflection subject but _GLIBCXX_DEBUG is > optional so maybe it won't be usable along with reflection with this > patch. It doesn't sound like a big deal to me but if it is then I'm > ready to cut again all debug check when in consteval mode or when > reflection is activated. > > > Yes, I share the same concerns. This is a lot of extra code to run > > during constant evaluation, for unclear benefit. > > It's a lot of extra code to compile in the consteval expressions but > less code written, see the cleanup in <vector> and <inplace_vector>. > Future move of containers like the unordered ones will be much more > transparent for the _GLIBCXX_DEBUG mode. > > _GLIBCXX_DEBUG is already adding extra work to the compiler, I would > prefer this extra work to serve a purpose like documented so do minimal > checks just forgetting about tracking container's iterators. > > > > > This would allow us to diagnose some uses of invalid iterators, like > > the topic of https://cplusplus.github.io/LWG/issue2256 > > Currently that code Just Works, because there is a valid object at > > that location, and the rule about invalidating iterators is only > > enforced with debug mode, so not during constant evaluation: > > > > #include <vector> > > #include <cassert> > > > > constexpr bool f() > > { > > typedef std::vector<int> C; > > C c = {1, 2, 3, 4}; > > C::iterator i = c.begin() + 1; > > C::iterator j = c.end() - 1; > > assert(*i == 2); > > assert(*j == 4); > > c.erase(c.begin()); > > return *i == 3; // Why is this not perfectly fine?! > > } > This won't be detected in consteval, container's iterators are not tracked. > > > > static_assert(f()); > > > > But I don't think I really care about this. There *is* a valid object, > > and if there wasn't, it would fail to compile. > >
