libstdc++ debug mode ideas 3
Benjamin Kosnik
bkoz@redhat.com
Wed Aug 6 19:29:00 GMT 2003
Begin forwarded message:
Date: Wed, 30 Jul 2003 11:30:39 -0700
From: Doug Gregor <dgregor@apple.com>
To: Gabriel Dos Reis <gdr@integrable-solutions.net>
Cc: Benjamin Kosnik <bkoz@redhat.com>
Subject: Re: [libstdc++ PATCH] libstdc++ debug mode (second try)
On Wednesday, July 30, 2003, at 10:21AM, Gabriel Dos Reis wrote:
> | The fact is that, in the absence of a perfect template aliasing
> model,
> | compiling part of a program in release mode and part of it in debug
> | mode is an ODR violation. If you agree with this, then I only see two
> | options:
> | (1) Find that perfect template aliasing model, or
> | (2) Manage the ODR violation so that it can't cause trouble.
>
> I do not think it is a template aliasing model and that finding that
> template alising model makes the problem (if there is one) go away.
>
> The template-name is primarily there to provide name commonality.
> What is being violated is not the declaration of the template-name,
> but the ODR for the entity being named by the template.
I think a perfect template aliasing model would make the problem go
away because we could do this:
namespace std {
namespace __release {
template<typename T, typename Allocator = std::allocator<T> >
class vector; // define release-mode vector
}
namespace __debug {
template<typename T, typename Allocator = std::allocator<T> >
class vector; // define debug-mode vector
}
}
Then, we add some directive that makes std::vector alias
std::__release::vector (when we're in release mode) or
std::__debug::vector (when we're in debug mode). A using declaration
very nearly gets us there, except that it breaks specialization:
namespace std {
#ifdef _GLIBCXX_DEBUG
using __debug::vector;
#else
using __release::vector;
#endif
}
I think your template aliasing proposal would let us do this:
namespace std {
#ifdef _GLIBCXX_DEBUG
template<typename T, typename Allocator=std::allocator<T> >
using vector = __debug::vector<T, Allocator>;
#else
template<typename T, typename Allocator=std::allocator<T> >
using vector = __release::vector<T, Allocator>;
#endif
}
> | I see that include <debug/vector> makes std::vector the debug
> | version even if we are compiling in release mode.
>
> I must confess my sympathy for this approach. It is the most simple
> semantics I would expect.
Okay. We're trading off the ability to easily switch a particular
container instance to debug mode (e.g., by changing std::vector<...> to
__gnu_debug::vector<...> in the source) with the ability to change all
containers to debug versions (e.g., by including <debug/vector> instead
of <vector>). I personally think the former is more important, because
I suspect that users would prefer to debug programs that crash, say,
after an iterator dereference by turning debugging on only for a few
suspect container instances and compiling only a little code. The
<debug/vector> model will turn on debugging for a lot more container
instances, and I wonder how much use it would get vs. just turning on
_GLIBCXX_DEBUG.
> | This differs from my
> | original patch, where <debug/vector> declares a debugging vector as
> | __gnu_debug::vector (regardless of whether or not we're in debug
> | mode). The benefit of your approach is that users can change one
> | #include to get debugging for a certain container type; the
> | disadvantage is that you can't change it for a single container
> | instance (since there is no separate __gnu_debug::vector to use). The
> | other issue is that
> |
> | #include <vector>
> | #include <debug/vector>
> |
> | will fail to compile in release mode, because std::vector will be
> | defined twice and __std::vector will not be defined at all. With this
> | methodology, the best we could do would be to emit a warning that the
> | debug-mode vector will _not_ be used, and then skip the debug
> | version. I wonder how many users would leave a stray <debug/vector>
> | somewhere in their program and wonder why things are running slowly.
>
> I think we should simply take that, we should avoid inclusion order
> dependency and we should avoid second-guessing the programmer, by
> assuming that he is stupid. I'm not sure how we can reconsile the
> above criteria but I will certainly object to changing the semantics
> behind the back of the user.
Any idea on how we can avoid the inclusion-order dependencies? If we
see both <debug/vector> and <vector>, so we always pick the debug
version? The release version? AFAICT, we're stuck with the first one
that's included (because it defines std::vector), and I think that's a
bit confusing.
Doug
More information about the Libstdc++
mailing list