debug mode checks in std::string

Jonathan Wakely jwakely.gcc@gmail.com
Sat Apr 2 17:24:00 GMT 2011


(This has probably been discussed before, maybe even by me, so
pointers to previous discussions are welcome.)

Firstly, should __gnu_cxx::__null_pointer in <ext/type_traits.h> use
__builtin_expect ?
We expect strings to be constructed with non-null pointers.


Several std::string members use __glibcxx_check_string and
__glibcxx_check_string_len, but those macros only assert when
_GLIBCXX_DEBUG_PEDANTIC is active - why?

The check_string macro is used where a non-null string is always required,
because there must be at least a null-terminator. That requirement is
made explicit in C++0x:
Requires: s points to an array of at least traits::length(s) + 1
elements of charT.

Only requiring non-null with PEDANTIC implies a GNU-extension which
accepts null strings, but that's only true for the constructor and in
the other members we go
ahead and call traits::length which just segfaults.  I think a
debug-mode assertion failure is preferable to a segfault and you
shouldn't have to use PEDANTIC to get that.

These only check for non-null with PEDANTIC but should always require
non-null or they segfault:

string::append(const char*)
string::assign(const char*)
string::insert(size_type, const char*)
string::replace(size_type, size_type, const char*)
string::replace(iterator, iterator, const char*)
string::rfind(const char*, size_type)
string::find_first_of(const char*, size_type)
string::find_last_of(const char*, size_type)
string::find_first_not_of(const char*, size_type)
string::find_last_not_of(const char*, size_type)

I think this would make more sense in debug/macros.h

#define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
#ifdef _GLIBCXX_DEBUG_PEDANTIC
#  define __glibcxx_check_string_len(_String,_Len) \
      _GLIBCXX_DEBUG_ASSERT(_String != 0)
#else
#  define __glibcxx_check_string_len(_String,_Len) \
      _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
#endif

i.e. always require non-null if no length is given (because the string must
contain at least a null-terminator).

As a gnu-extension accept null pointers if length is given as zero,
but always reject them in PEDANTIC mode.


Additionally, the debug mode docs need updating, they suggest
disabling EXTERN_TEMPLATE for debug mode strings, but that's done
automatically in c++config, and they also claim there is a debug mode
assertion for non-null string in PEDANTIC mode, but AFAICT we always
throw an exception from _S_construct even in PEDANTIC mode.



More information about the Libstdc++ mailing list