Empty pointer to std::string

M

mr_sorcerer

Hi!

I just found something interesting.
I mean what do you think about this:

char *p = 0;
std::string str = p;

Why std::string doesn't check null pointers?

Why not doin' some checking:

class String : public std::string
{
public:
String():std::string() {}
String(const char *str):std::string() {
if(str == 0)
*this = std::string();
else
*this = std::string(str);
}
String(const std::string& str):std::string(str) {}
};

This is only an example, 'cause i didn't want to write from scratch
string class, so i just derived. :)
 
K

Kai-Uwe Bux

mr_sorcerer said:
Hi!

I just found something interesting.
I mean what do you think about this:

char *p = 0;
std::string str = p;

Why std::string doesn't check null pointers?

Because the standard prefers undefined behavior to wasting CPU cycles.

Why not doin' some checking:

class String : public std::string
{
public:
String():std::string() {}
String(const char *str):std::string() {
if(str == 0)
*this = std::string();
else
*this = std::string(str);
}
String(const std::string& str):std::string(str) {}
};

This is only an example, 'cause i didn't want to write from scratch
string class, so i just derived. :)

Feel free to do that. I would prefer an assert( str != 0 ). That way, I
would use String for testing and could replace it with std::string when I
am convinced that I avoided UB successfully.

BTW: I find it is somewhat neat to have a namespace debug that provides
debug::vector<>, debug::string, ... with defined behavior (assert) instead
of UB.


Best

Kai-Uwe Bux
 
R

Roland Pibinger

Because the standard prefers undefined behavior to wasting CPU cycles.

OTOH, a public member function should validate input. I'd consider
that good style.
BTW: I find it is somewhat neat to have a namespace debug that provides
debug::vector<>, debug::string, ... with defined behavior (assert) instead
of UB.

assert is en-/disabled by the NDEBUG #define. assert uses 'namespace
NDEBUG' ;-)
 
K

Kai-Uwe Bux

Roland said:
OTOH, a public member function should validate input. I'd consider
that good style.

True, but that is a quality of implementation issue. The standard does no
require public member functions of standard containers to do any of that.
Of course, you could just purchase / implement and then use a standard
library implementation that includes the assert() statements you want.

assert is en-/disabled by the NDEBUG #define. assert uses 'namespace
NDEBUG' ;-)

Yes. However, that only works if you are using an standard library
implementation that does input validation, range checking, and so on.
Otherwise, you have to roll your own code.


Best

Kai-Uwe Bux
 
J

James Kanze

mr_sorcerer wrote:
Because the standard prefers undefined behavior to wasting CPU cycles.

Because the standard prefers to leave the choice up to the
implementors, so they can do whatever is best for their
customers. (The systems I use all *do* check, and the above
code will systematically generate a core dump.)

Most systems do. There's usually no need for explicit checking,
of course, because the hardware does it implicitly,
automatically. But the result is the same: you get a core dump
(or the equivalent), which is the desired behavior in case of
programmer error.

No. A null pointer is *not* an empty string. If you need to
support null values, you need something like Fallible (although
the names of the functions and the behavior in the invalid case
should probably be different).
Feel free to do that. I would prefer an assert( str != 0 ).

Why? On most platforms, the only thing that will buy you is a
different error message. I can't imagine an implementation of
std::string which doesn't access the pointer in the constructor,
and accessing a null pointer is a certain core dump under Unix
or Windows.
 
J

James Kanze

Yes. However, that only works if you are using an standard library
implementation that does input validation, range checking, and so on.

Both VC++ and g++ do. If you're developping under Windows, you
certainly have access to VC++ (it's free), and if you're
developping under Unix, you certainly have access to g++ (also
free). Even if your final target compiler is something else,
there's nothing to stop you from using one of these compilers
during development.
 
R

Roland Pibinger

Most systems do. There's usually no need for explicit checking,
of course, because the hardware does it implicitly,
automatically. But the result is the same: you get a core dump
(or the equivalent), which is the desired behavior in case of
programmer error.

One 'expected' behavior would be a null_pointer_exception (derived
from std::runtime_error).
No. A null pointer is *not* an empty string.

Although a null pointer is not an empty string it could be converted
to an empty string by a constructor. This is not elegant but makes
sense for strings (not for other types).
 
G

Greg Comeau

One 'expected' behavior would be a null_pointer_exception (derived
from std::runtime_error).


Although a null pointer is not an empty string it could be converted
to an empty string by a constructor.

True, but...
This is not elegant but makes
sense for strings (not for other types).

....be careful with that kind of suggestion.
Which I'm certain is part of James's point.
 
B

Bo Persson

Roland Pibinger wrote:
:: On 5 Apr 2007 01:47:36 -0700, "James Kanze" wrote:
:::: mr_sorcerer wrote:
::::: Why std::string doesn't check null pointers?
:::
:::: Because the standard prefers undefined behavior to wasting CPU
:::: cycles.
:::
::::: Why not doin' some checking:
:::
::: Most systems do. There's usually no need for explicit checking,
::: of course, because the hardware does it implicitly,
::: automatically. But the result is the same: you get a core dump
::: (or the equivalent), which is the desired behavior in case of
::: programmer error.
::
:: One 'expected' behavior would be a null_pointer_exception (derived
:: from std::runtime_error).

And that would be extremely expensive on platforms without hardware support.
Those platforms are often the ones where you cannot afford the performance
loss.


Bo Persson
 
J

James Kanze

On 5 Apr 2007 01:47:36 -0700, "James Kanze" wrote:
One 'expected' behavior would be a null_pointer_exception (derived
from std::runtime_error).

So that the error can be hidden, and not show up immediately. I
wouldn't use such a class in production software.
Although a null pointer is not an empty string it could be converted
to an empty string by a constructor.

Certainly. You can convert anything to anything with a suitable
constructor.

Whether it makes sense or not is another question.
This is not elegant but makes
sense for strings (not for other types).

Are you saying that NULL and "" are the same thing in C? I've
certainly never used them for the same thing in C, and when I
need the equivalent of a C function which returns a char const*
which can be null, in C++, I use Fallible< std::string >. An
empty string is NOT a null value (as anyone who has ever used a
data base can tell you).
 
D

Default User

Roland Pibinger wrote:


A small (but important) technical note. The proper separator for .sigs
is "-- " (dash dash space). Yours is missing the space. Correct
separators allow newsreaders to auto-trim signatures.





Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,301
Messages
2,571,549
Members
48,295
Latest member
JayKillian
Top