debug algorithms

François Dumont francois.cppdevs@free.fr
Mon Sep 6 19:44:00 GMT 2010


Hi

   I have been working on generalization of the __gnu_debug::__base 
function in debug algorithms. Rather than simply adding a new macro and 
call it all around algos I prefered to try to change the design of debug 
algos to adopt the same technique as the one used on debug containers, 
the normal algo in std::__norm and the debug algo in std::__debug. I did 
so for 2 reasons:
1. I think debug mode code (in include/debug) should be as much as 
possible isolated from the normal code (mostly in include/bits).
2. Algos are used internally to implement other algos or containers that 
already have a debug mode. This is a source of redundant debug checks. 
With 2 versions of algos we will be able to chose internally the version 
that should be called.

   I have started to work on algos in stl_algobase.h. I move code in 
this file in 3 different namespaces:
- std for Standard algos without debug mode
- std::__norm for Standard algos with a debug mode
- __gnu_cxx for other code that is to say helper functions or struct.

   I move many things in __gnu_cxx in order to be able to use it in 
other files without considering if the debug mode is activated or not 
and without using _GLIBCXX_STD_D macro too much. Moreover it avoids 
pollution of the std namespace.

   This is the result on my initial attempt:

Executing on host: 
/home/fdt/dev/gcc/host-x86_64-unknown-linux-gnu/gcc/g++ -shared-libgcc 
-B/home/fdt/dev/gcc/host-x86_64-unknown-linux-gnu/gcc -nostdinc++ 
-L/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/src 
-L/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs 
-B/home/fdt/x86_64-unknown-linux-gnu/bin/ 
-B/home/fdt/x86_64-unknown-linux-gnu/lib/ -isystem 
/home/fdt/x86_64-unknown-linux-gnu/include -isystem 
/home/fdt/x86_64-unknown-linux-gnu/sys-include 
-B/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs -g 
-O2 -D_GLIBCXX_ASSERT -fmessage-length=0 -ffunction-sections 
-fdata-sections -g -O2 -D_GNU_SOURCE  -DLOCALEDIR="." -nostdinc++ 
-I/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu 
-I/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include 
-I/home/fdt/dev/gcc/libstdc++-v3/libsupc++ 
-I/home/fdt/dev/gcc/libstdc++-v3/include/backward 
-I/home/fdt/dev/gcc/libstdc++-v3/testsuite/util 
/home/fdt/dev/gcc/libstdc++-v3/testsuite/25_algorithms/copy/1.cc    
-include bits/stdc++.h ./libtestc++.a -Wl,--gc-sections  -lm   
-D_GLIBCXX_DEBUG -o ./1.exe    (timeout = 600)
/home/fdt/dev/gcc/libstdc++-v3/testsuite/25_algorithms/copy/1.cc: In 
function 'void test01()':
/home/fdt/dev/gcc/libstdc++-v3/testsuite/25_algorithms/copy/1.cc:38:28: 
error: call of overloaded 'copy(const int [17], const int*, 
std::__debug::vector<int>::iterator)' is ambiguous
/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include/debug/algobase.h:52:5: 
note: candidates are: _OI std::__debug::copy(_II, _II, _OI) [with _II = 
const int*, _OI = 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, 
std::__norm::vector<int, std::allocator<int> > >, 
std::__debug::vector<int> >]
/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:462:5: 
note:                 _OI std::__norm::copy(_II, _II, _OI) [with _II = 
const int*, _OI = 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, 
std::__norm::vector<int, std::allocator<int> > >, 
std::__debug::vector<int> >]

The compilation error comes from an ambiguity on the copy invocation 
when it is called using vector iterator, when called with int pointers 
there is no problem. The version in std::__debug is considered because 
of the namespace injection and I realized that the std::__norm was 
concidered because of ADL as the __gnu_debug::_Safe_iterator is 
instanciated with a type that contains a reference to the std::__norm 
namespace. I didn't want to use macros so the only solution I saw was to 
avoid this reference to the std::__norm namespace and I change the 
_Safe_iterator template parameters to still take the container, 
std::__debug::vector, and a boolean constant to indicate if it should be 
a constant iterator or not.

   Once done this is the new result:

/home/fdt/dev/gcc/libstdc++-v3/testsuite/25_algorithms/copy/1.cc: In 
function 'void test01()':
/home/fdt/dev/gcc/libstdc++-v3/testsuite/25_algorithms/copy/1.cc:38:28: 
error: call of overloaded 'copy(const int [17], const int*, 
std::__debug::vector<int>::iterator)' is ambiguous
/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include/debug/algobase.h:52:5: 
note: candidates are: _OI std::__debug::copy(_II, _II, _OI) [with _II = 
const int*, _OI = __gnu_debug::
_Safe_iterator<std::__debug::vector<int>, false>]
/home/fdt/dev/gcc/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:462:5: 
note:                 _OI std::__norm::copy(_II, _II, _OI) [with _II = 
const int*, _OI = __gnu_debu
g::_Safe_iterator<std::__debug::vector<int>, false>]

   The problem is still present because std::__debug::vector inherits 
from std::__norm::vector and so the std::__norm namespace is injected 
again. So I remove this inheritance and replace it with a conversion 
operator to still be able to mix debug and normal implementations in the 
same translation unit. I attached a beta version of this patch to show 
you how the code is impacted, not to apply of course.

   IMHO, even if this patch has a lot of impact on the code, it is 100% 
compatible with existing user code and is a design enhancement in 
addition to a performance enhancement for the debug mode.

   What is your opinion about this new design ? Can I generalize it and 
run the whole testsuite to see that nothing is broken as expected.

Francois

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: debug.patch
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20100906/9a435740/attachment.ksh>


More information about the Libstdc++ mailing list