Hi Tobi,
On Wed, 2006-09-20 at 12:23 -0500, Tobias Raufer wrote:
> Hi RootTalk,
>
> I am using version 5.11/02 built from source on a Suse 10 system.
>
> I seem to have a problem when using STL strings in CINT. Consider the
> following short macro:
...
> string testString = "Hello";
> cout << "Find x: " << testString.find("x") << endl;
> cout << "string::npos: " << string::npos << endl;
...
> root [0] .x test.C
> Find x: 4294967295
> string::npos: -1
> root [1]
Believe it or not, but 4294967295 and -1 are the same :) If you do
> root -l root [0] #include <string> root [1] std::string s("foo") root [2] std::string::npos (const enum string::)(-1) root [3] s.find("bla") (const unsigned int)4294967295 root [4] int(s.find("bla")) (const int)(-1) root [5] s.find("bla") == std::string::npos (const unsigned int)1 root [6] s.find("foo") == std::string::npos (const unsigned int)0 unsigned(std::string::npos) (const unsigned int)4294967295
you will see why. 4294967295 is overflow of an unsigned (32bit) integer. Hence, the implicit promotion the return value of std::string::find to an signed integer (or is it std::string::npos that's demoted to an unsigned integer?) makes the comparison work.
The standard actually specifies npos as (section 21.3, clause 6)
template <class charT, class traits=char_traits<charT>, Allocator=allocator<charT> > class basic_string { ... typedef typename Allocator::size_type size_type; ... static const size_type npos = -1; ... };
Hence, `-1' is _the_ value of npos (appropriately casted), while `size_type' is defined by the third template parameter. You could imagine a passing an argument like
class CharAllocator
{
... typedef float size_type; ...
even though it doesn't make much sense (and could be disallowed by other uses of size_type). However, the assignment `npos = -1' is still valid, as long as the long int value -1 can be converted to size_type.
> Is there a problem with string::npos in CINT?
Nope. The arch-typical usage of npos is something like
std::string s("foo"); std::string::size_type i = s.find("bar"); if (i == std::string::npos) { std::cerr << "Argh!, \"bar\" not found in \"" << s << "\"" << std::endl; exit(1); }
And that's really the only way to use `npos'.
> When I compile the same
> macro with ACliC, everything works fine.
Your script _does_ work, even in interpreted mode. The output is perfectly legitimate according to the standard. Note, that the implementation of C++ is pretty free to choose these things (what type is size_type exactly?), and there's nothing wrong in CINT using a different allocator for strings made in the interpreter - in fact, it's probably a very good idea.
Yours,
-- ___ | Christian Holm Christensen |_| | ------------------------------------------------------------- | | Address: Sankt Hansgade 23, 1. th. Phone: (+45) 35 35 96 91 _| DK-2200 Copenhagen N Cell: (+45) 24 61 85 91 _| Denmark Office: (+45) 353 25 404 ____| Email: cholm_at_nbi.dk Web: www.nbi.dk/~cholm | |Received on Thu Sep 21 2006 - 02:33:32 MEST
This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:32:01 MET