Where to place a constant?

L

Lasse Skyum

I have my own string class that I'm generally verry fond of compared to
std::string. For that same reason I'm trying to improve a little on it.

Since manny objects in my project will contain strings of empty size "" I
thought it would be a good idea to share en empty string allocation between
all uninitialized strings.

However I have no idea where to place this constant? :-S
I tried this:

class CBL_String
{
public:
static char * strEmptyString = ""; // it complaines about this...

};

If I do don't initialize it in the class-spec but in a cpp file I'm not sure
that it is actually initialized before used, by some other global CBL_String
variable... right?

char *CBL_String::strEmptyString = "";


Suggestions anyone?
 
L

Lasse Skyum

You'd be much better off using std::string.

Okay... maybe so, but I don't really se why? CBL_String helps me in manny
different ways and has never been the source of any bugs in my programs.

Does std::string have a shared empty string or maybe it uses NULL as an
empty string?
If std::string also allocated an empty string if not initialized, then I see
no reason what so ever to use it...

BTW, I've also written my own CBL_ArrayList as an equivalent to vector...
ony differenceis the ability to automatically shrink if a flag is set. For
some odd reason it also outperformes vector in my insert/remove benchmarks,
probably just a bunch of settings or something.

I'm sure all this is also in Boost (or whatever C++ extentions there might
be) but I've learned so much be writing it my self.

Anyway... I just wanted to have an initialized constant :) Might also be
relevant for other things!
 
?

=?iso-8859-1?Q?Andr=E9_P=F6nitz?=

Lasse Skyum said:
Okay... maybe so, but I don't really se why?

Simply because std::string is 'the standard'. Using it makes your code
better re-usable for starters.
Does std::string have a shared empty string or maybe it uses NULL as an
empty string?

This would be an implementation detail.
If std::string also allocated an empty string if not initialized, then I see
no reason what so ever to use it...

A decent std::string implementation will make sure that 'std::string s;' is
_really_ cheap. I would not expect any dynamic allocation in this case.
BTW, I've also written my own CBL_ArrayList as an equivalent to vector...

This strikes me as an even worse idea than having a 'new' string class
(which might have its uses for certain encoding related reasons)
ony differenceis the ability to automatically shrink if a flag is set.
For some odd reason it also outperformes vector in my insert/remove
benchmarks, probably just a bunch of settings or something.

Would be nice to see some minimal code demonstrating these results.
It's not easy to believe unless you dropped some 'important' std::vector
characteristics.
I'm sure all this is also in Boost (or whatever C++ extentions there might
be) but I've learned so much be writing it my self.

Learning is always a good reason to re-write certain standard classes.
It is rarely a good enough reason for _using_ them, though ;-)

Andre' [who isn't particularly fond of std::string either but uses it
nevertheless]
 
R

Rolf Magnus

Lasse Skyum said:
Okay... maybe so, but I don't really se why? CBL_String helps me in
manny different ways and has never been the source of any bugs in my
programs.

Does std::string have a shared empty string or maybe it uses NULL as
an empty string?

I'd say that's implementation specific. Anyway, why do you think you
need such a shared ... ehm, nothing? I mean, an empty string has no
data to share. Its size is 0, so there is nothing to read from it, so
why would you need to share that 'nothing' between empty strings? Btw:
Do you actually have that many empty strings in real programs?
If std::string also allocated an empty string if not initialized, then
I see no reason what so ever to use it...

BTW, I've also written my own CBL_ArrayList as an equivalent to
vector... ony differenceis the ability to automatically shrink if a
flag is set.

If you're happy with your own containers and strings, it's IMHO ok to
use them. Of course, you'll limit code reusability somewhat.
For some odd reason it also outperformes vector in my
insert/remove benchmarks, probably just a bunch of settings or
something.

That again depends on the implementation you use, not only on settings.
I'm sure all this is also in Boost (or whatever C++ extentions there
might be) but I've learned so much be writing it my self.

That's of course a very good reason to write your own ones, but it is
not a reason to use them in real code :)
Anyway... I just wanted to have an initialized constant :) Might
also be relevant for other things!

If you want to be sure that your constant is initialized before other
static objects, you might want to use the singleton pattern.
 
L

Lasse Skyum

Would be nice to see some minimal code demonstrating these results.
It's not easy to believe unless you dropped some 'important' std::vector
characteristics.

Nope, it does all the copy-constructing and inplace new's needed to make it
work right. However not using allocators, just plain ol' malloc/free.

Nevermind... that's not what wanted to talk about in the first place.
 
L

Lasse Skyum

If you want to be sure that your constant is initialized before other
static objects, you might want to use the singleton pattern.

Singleton... well seems to be a lot of work and fiddeling just for
initializing a constant :-(
 
E

Evan Carew

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lasse said:
Nope, it does all the copy-constructing and inplace new's needed to make it
work right. However not using allocators, just plain ol' malloc/free.

Nevermind... that's not what wanted to talk about in the first place.
Sounds like that's the source of your performance gain right there. most
implementations use a new with a goodly bit of code in it to ensure safe
memory allocation, and if not, then gracefull notification.

Evan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAMMtaoo/Prlj9GScRAov6AJ948pesdtbnthcOEjUpXBJIKGFVFACfRCe5
OLn3htYOKLCUgi87kIKknHs=
=ZUUQ
-----END PGP SIGNATURE-----
 
T

Thomas Matthews

Lasse said:
I have my own string class that I'm generally verry fond of compared to
std::string. For that same reason I'm trying to improve a little on it.

Since manny objects in my project will contain strings of empty size "" I
thought it would be a good idea to share en empty string allocation between
all uninitialized strings.

However I have no idea where to place this constant? :-S
I tried this:

class CBL_String
{
public:
static char * strEmptyString = ""; // it complaines about this...

};

If I do don't initialize it in the class-spec but in a cpp file I'm not sure
that it is actually initialized before used, by some other global CBL_String
variable... right?

char *CBL_String::strEmptyString = "";


Suggestions anyone?

In the C++ specification, there is no order to initializing static
variables declared in global or local translation unit scope. Thus
most people initialize these variables in the constructor. Search
the web for "Scott Meyers variable initialization".

If the order of static variable initialization is important, then
use the Singleton design pattern or move the variables inside a
function. The rule for static variable initialization in a
function is "first use".

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
K

kevin collins

Lasse Skyum said:
I have my own string class that I'm generally verry fond of compared to
std::string. For that same reason I'm trying to improve a little on it.

Since manny objects in my project will contain strings of empty size "" I
thought it would be a good idea to share en empty string allocation between
all uninitialized strings.

However I have no idea where to place this constant? :-S
I tried this:

class CBL_String
{
public:
static char * strEmptyString = ""; // it complaines about this...

};

If I do don't initialize it in the class-spec but in a cpp file I'm not sure
that it is actually initialized before used, by some other global CBL_String
variable... right?

char *CBL_String::strEmptyString = "";


Suggestions anyone?

This compiles, try this.

class C
{
public:
static char* sk;
};
char* C::sk = "";

Put all that in a header file.

This thread is a good example of why you should not tell people what you are
doing. You will find that a great many of the regulars are much smarter
than you and instead of answering your question they will lecture you on how
and why you are doing the wrong damn thing.
 
R

Rolf Magnus

Lasse Skyum said:
Singleton... well seems to be a lot of work and fiddeling just for
initializing a constant :-(

It can be as simple as:

class CBL_String
{
    static const char * strEmptyString()
{
const char* const empty = "";
return empty;
}
};

Actually, even this should work:

class CBL_String
{
    static const char * strEmptyString()
{
return "";
}
};
 
N

Nick Hounsome

Lasse Skyum said:
I have my own string class that I'm generally verry fond of compared to
std::string. For that same reason I'm trying to improve a little on it.

Since manny objects in my project will contain strings of empty size "" I
thought it would be a good idea to share en empty string allocation between
all uninitialized strings.

However I have no idea where to place this constant? :-S
I tried this:

class CBL_String
{
public:
static char * strEmptyString = ""; // it complaines about this...

This is wrong for several reasons besides initialization:
strEmptyString = new char[10]; // this will compile!!
strEmptyString[3] = '!'; // This will also compile!!!

What you want is a constant string NOT an non-constant pointer to a
non-constant string.
This is declared as:

static const char EMPTY_STRING[]; // NB CONST

Define in cpp file:

const char CBL_String::EMPTY_STRING[] = "";

This does not require runtime initialization.
IF you don't use it in inline methods then it is better still to make it
file static rather than class static.
If I do don't initialize it in the class-spec but in a cpp file I'm not sure
that it is actually initialized before used, by some other global CBL_String
variable... right?

char *CBL_String::strEmptyString = "";

None of this simple stuff requires runtime initialization it just goes in
the data section
of the object file.
Suggestions anyone?

Don't use your own string - it may be wonderful but there are millions of
people out there who know
the std::string and only one who knows CBL_String.

What is the cost to your employer of you designing, coding, testing and
documenting your string?
Just documenting it as well as the std string would cost $1000!
What is the cost of future maintainers having to read your string docs
instead of just using stuff they already know?
 
L

Lasse Skyum

It can be as simple as:

class CBL_String
{
static const char * strEmptyString()
{
const char* const empty = "";
return empty;
}
};

Thanks Rolf, I'll check that one out!
 
L

Lasse Skyum

This compiles, try this.

class C
{
public:
static char* sk;
};
char* C::sk = "";

Put all that in a header file.

Thanks, I'll try it out... however not really understanding when exactly the
initialization is taking place.
This thread is a good example of why you should not tell people what you are
doing. You will find that a great many of the regulars are much smarter
than you and instead of answering your question they will lecture you on how
and why you are doing the wrong damn thing.

Yes, that tend to happen every time I post here :-(
 
A

Alf P. Steinbach

Thanks, I'll try it out...

Be sure to try it out with the header-file used in two different
compilation units of the same program.

In that case you'll get a linker error.

You can¹ avoid the linker error by adding 'const' here and there, but the
effect of that is that you specify internal linkage, i.e. multiple copies,
which is what you were trying to avoid IIRC (not that # of copies matters).


however not really understanding when exactly the
initialization is taking place.

Initialization of namespace level statics in a compilation unit is
performed before the first call of a function in that compilation unit,
including call of a constructor.


On the contrary, this thread is a good example of why you should tell
people what you are doing.

The best general advice so far is to use std::string.

The best advice so far regarding how to provide a string constant is
the C++ singleton pattern (a function containing a static variable).

Yes, that tend to happen every time I post here :-(



¹) At least I think so. But I have fever and am not thinking clearly,
and darned if I'm going to check out something you should check out.
 

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,161
Messages
2,570,892
Members
47,428
Latest member
RosalieQui

Latest Threads

Top