Re: Global Variables
Seungbeom Kim wrote:
Maxim Yegorushkin wrote:
pramod wrote:
What's the difference between:
const char* pS1 = "abc"; and
const char pS2[] = "abc";
[...]
When should one be preferred over the other?
http://people.redhat.com/drepper/dsohowto.pdf gives an
explanation why the second definition is preferred. It is
one less relocation for a dynamic linker.
That's a very system-specific reason to consider;
not everyone writes shared libraries on Unix.
Elf is, I think, widespread even outside of Unix. But the paper
does remain very specific to a specific object file format. And
the object file format doesn't map directly to specific C++
concepts; the compiler uses it, *as* *needed*, to implement
these concepts.
In addition, some explanations in the quoted paper is
suspicious; it shows a strong implication that the pointer
version is inferior, but I don't think it necessarily gives
the compiler a harder time and it can be the opposite in some
cases. In particular, if the declaration is in a local scope,
the array version has to initialize the array by copying the
string, but the pointer version has to initialize the pointer
by just setting the pointer.
If the string is very long, the pointer version is definitly
faster for a local non-static variable. On the other hand, if
the values are never changed (which is necessarily the case,
since the object is const), and the object is always initialized
with the same value (also the case), then you might as well
declare it static as well. (The compiler can't automatically
treat it as if it were static, since if the function is called
recursively, the addresses of the object must compare
different.)
[By using the array version,]
we save one pointer variable in the non-sharable data
segment,
Who says the compiler cannot optimize the pointer variable
away?
It would be difficult, unless the pointer was const (and not
just a pointer to const).
The whole point in using a pointer is that you need a pointer.
The whole point in not declaring it const is that someone can
modify it.
[...]
some linkers perform suffix optimizations:
const char s1[] = "some string";
const char s2[] = "string";
The symbol s2 can be a reference to the fifth character of
the longer string.
Is the implementation allowed to make s2 a sub-object of s1? I.e.
assert(not (s1 <= s2 && s2 < s1 + sizeof(s1)))
Is it possible for this assertion to fail?
Yes. It is based on the undefined results of comparing for
inequality pointers not pointing into the same object. On the
other hand:
for ( char const* p1 = s1 ; p1 != s1 + sizeof( s1 ) ; ++ p1) {
assert( p1 != s2 ) ;
}
Is guaranteed to succeed. I can even imagine some programs
counting on this fact.
I'm not very sure, but I'd be surprised if it could fail.
Anyway, this optimization is definitely possible in the
pointer version.
Correct. Because the standard explicitly allows string
constants to overlap.
So far, I haven't found a single argument of the author for
the array version convincing. Please correct me if I'm wrong
in any point.
I wasn't very impressed by the paper either.
The fundamental argument isn't for the array version. The
fundamental argument is that the two declarations declare
different things. You choose one or the other according to what
you want to do. In cases where both can be used, you choose one
or the other according to the message you want to pass to the
reader.
--
James Kanze GABI Software
Conseils en informatique orient��e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S��mard, 78210 St.-Cyr-l'��cole,
France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]