By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,149 Members | 885 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,149 IT Pros & Developers. It's quick & easy.

String - substr query

P: n/a
sks
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
My questions are :
1. Is this behaviour correct ? ( Or should this case be an exception?)
2. If it is correct, what is the idea behind this behaviour ?

using namespace std;
#include <iostream>
#include <string>
int main()
{
string s("This is a test string");
cout << s.substr(0,-1) << endl;
return 0;
}
Thanks,
Sumedha Swamy

Jul 12 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
In article <11**********************@p79g2000cwp.googlegroups .com>,
"sks" <su**********@gmail.comwrote:
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
My questions are :
1. Is this behaviour correct ? ( Or should this case be an exception?)
Yes.
2. If it is correct, what is the idea behind this behaviour ?

using namespace std;
#include <iostream>
#include <string>
int main()
{
string s("This is a test string");
cout << s.substr(0,-1) << endl;
return 0;
}
basic_string basic_string::substr(size_type pos = 0, size_type n = npos)
const

Constructs a string from a substring of s. The substring begins at
character position pos and terminates at character position pos + n or
at the end of s, whichever comes first.

Note that n is of type size_type which is unsigned, so passing -1
probably makes for a very big number.
Jul 12 '06 #2

P: n/a

sks wrote:
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
There is no such thing as a substr parameter lesser than 0 as the param
type is unsigned.
My questions are :
1. Is this behaviour correct ? ( Or should this case be an exception?)
2. If it is correct, what is the idea behind this behaviour ?

using namespace std;
#include <iostream>
#include <string>
int main()
{
string s("This is a test string");
cout << s.substr(0,-1) << endl;
Passed parameter is not -1 but a very large positive number on most
architectures.
return 0;
}
Thanks,
Sumedha Swamy
Jul 12 '06 #3

P: n/a
sks wrote:
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
My questions are :
1. Is this behaviour correct ? ( Or should this case be an exception?)
Somewhat.
2. If it is correct, what is the idea behind this behaviour ?
The idea is that substr() should return the whole string if the second
argument is larger than the length of the string.
using namespace std;
#include <iostream>
#include <string>
int main()
{
string s("This is a test string");
cout << s.substr(0,-1) << endl;
return 0;
}
The signature of substr() is:

basic_string<charT,traits,Allocator>
substr(size_type pos = 0, size_type n = npos) const;

As you can see, the length argument is of type size_type, which is inherited
from the Allocator. You are using std::allocator<charT>, whose size_type is
std::size_t and therefore unsigned. You are passing -1, which wraps around
and yields in fact the maximum number that can be represented.
Best

Kai-Uwe Bux
Jul 12 '06 #4

P: n/a
"sks" <su**********@gmail.comwrote in message
news:11**********************@p79g2000cwp.googlegr oups.com...
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
My questions are :
1. Is this behaviour correct ? ( Or should this case be an exception?)
2. If it is correct, what is the idea behind this behaviour ?

using namespace std;
#include <iostream>
#include <string>
int main()
{
string s("This is a test string");
cout << s.substr(0,-1) << endl;
return 0;
}
Thanks,
Sumedha Swamy
It is correct by the fact that substr's second paramter is unsigned. size_t
which (on my implementation) is a 4 byte unsigned int.

Passing a negative number as an unsigned parameter actually makes a very BIG
number. The high bit is set in signed numbers, and in unsigned the high bit
is treated as a high number. 2147483648 in a 32 bit unsigned int. If your
system uses 2's compliment (most do) -1 as a signed is the largest value the
number can hold, because all bits are set for -1 (google up on 2's
compliment to find out why).

Incidently, -1 is actually teh value used for npos (no position) which is
the largest value for size_t (all bits set).

So, saying
s.substr(0,-1)
is actually the same as saying
s.substr(0, 4294967295)

You can also achieve the exact same thing by leaving off the second parm.
s.substr(0)
If the second parm is left off, it defaults to npos which is 4294967295 on
32 bit systems.
Jul 12 '06 #5

P: n/a
sks wrote:
Hi,

Here is a small program that is wrtten to simply use substr.
When the second parameter in substr (length of the string to be
extracted) is lesser than 0, the output is the entire string (I'm using
gcc 4.1.0)
As others pointed out, the lengt parameter of substr is size_type,
unsigned.

But being often enough enoyed by the signed/unsigned warnings of
g++/vc++, I wondered why gcc didn't warn you.

Having installed a few versions, I tried:

$ g++-2.95.4 -Wall -O2 ref.cc -o ref && ./ref
This is a test string

$ g++-3.3.6 -Wall -O2 ref.cc -o ref && ./ref
ref.cc: In function `int main()':
ref.cc:8: warning: passing negative value `-1' for converting 2 of `
std::basic_string<_CharT, _Traits, _Allocstd::basic_string<_CharT,
_Traits, _Alloc>::substr(typename _Alloc::size_type, typename
_Alloc::size_type) const [with _CharT = char, _Traits =
std::char_traits<char>, _Alloc = std::allocator<char>]'
This is a test string

$ g++-4.0.3 -Wall -O2 ref.cc -o ref && ./ref
ref.cc: In function 'int main()':
ref.cc:8: warning: passing negative value '-0x00000000000000001' for
argument 2 to 'std::basic_string<_CharT, _Traits, _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>::substr(typename
_Alloc::size_type, typename _Alloc::size_type) const [with _CharT =
char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'
This is a test string

$ g++-4.1.1 -Wall -O2 ref.cc -o ref && ./ref
This is a test string

So the various g++ versions somtimes warn, sometimes don't. You just
happened to use a version that doesn't. Wonder why 4.1 stopped warning
again. (It's not in the .h files, as the cpp (-E) output generated by
4.0.3 doesn't generate a warning with 4.1.1, the reverse does warn)

Jul 12 '06 #6

P: n/a
sks
Hi,
Thanks all of you. I'm now convinced that the behaviour is correct.
But as joosteto has pointed out, gcc should have atleast given me a
warning.

Thanks once again.

Sumedha Swamy

Jul 13 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.