struct Test
{
static const char* name()
{
return "XYZ";
}
static const char* name2()
{
static const char n[] = "XYZ";
return n;
}
};
I know (?) that Test::name2() is both legal and portable but Test::name()
seems to work too. At least with VC++7 and some old version of gcc.
The question: Is Test::name() legal?
/Mathias
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
> Consider the following:
>
> struct Test
> {
> static const char* name()
> {
> return "XYZ";
> }
> static const char* name2()
> {
> static const char n[] = "XYZ";
> return n;
> }
> };
>
> I know (?) that Test::name2() is both legal and portable but
> Test::name() seems to work too. At least with VC++7 and some old version
> of gcc.
>
> The question: Is Test::name() legal?
Yes, it is. Pointers to string literals remain valid for the whole
execution time of a C++ program.
C++ standard, 2.13.4 (1): String literals [lex.string]
> An ordinary string literal has type "array of n const char" and static
> storage duration (3.7), [...].
3.7.1 (1): Static storage duration [basic.stc.static]
> All objects which neither have dynamic storage duration nor are local
> have static storage duration. The storage for these objects shall last
> for the duration of the program (3.6.2, 3.6.3).
HTH,
sk
>Consider the following:
>
>struct Test
>{
> static const char* name()
> {
> return "XYZ";
> }
> static const char* name2()
> {
> static const char n[] = "XYZ";
> return n;
> }
>};
>
>I know (?) that Test::name2() is both legal and portable but Test::name()
>seems to work too. At least with VC++7 and some old version of gcc.
>
>The question: Is Test::name() legal?
>
Quite the contrary. Let me be a little pedantic, but I think it's
important to help understanding here. String-literals are not objects,
they are expressions that designate objects (therefore it's quite
improper to say "address of a string literal" :) Note BTW that they
are the only kind of literal that are l-values).
The object a string literal refers to (an array of const char or const
wchar_t) has always static duration (2.13.4).
Therefore Test::name is (thanks to array-to-pointer conversion)
perfectly right: it returns the address of the first element of an
array that remains undestroyed at function exit; Test::name2() returns
instead the address of n[0], which is a local array (initialized a
string literal).
Hope this helps,
Genny.
Yes it is. Why? You seem to mix up local variables with string
literals. The expression "XYZ" is a string literal. A string literal
(usually) gets memory allocated in some read-only memory area. So there
is only one XYZ, somewhere in the memory. When you write down this
"XYZ", into the code, it will "mean" the address of that (basically
static) memory area. And you return this address from Test::name().
You can test it yourself by calling Test::name() many times, from main,
from functions called from main (so that the "stack is moved") and print
the address. You will see, that the address is always the same. If you
know a bit more about your architecture, you may even find out, that
this address is in a read-only memory area (page, segment, whatever it
is called there).
Attila
|> Consider the following:
|> struct Test
|> {
|> static const char* name()
|> {
|> return "XYZ";
|> }
|> static const char* name2()
|> {
|> static const char n[] = "XYZ";
|> return n;
|> }
|> };
|> I know (?) that Test::name2() is both legal and portable but
|> Test::name() seems to work too. At least with VC++7 and some old
|> version of gcc.
|> The question: Is Test::name() legal?
The question is, what is the difference in the two, other than the fact
that the second has a locally visible name?
The first is not only legal, I think it is the more frequent idiom. (It
is certainly more frequent in my code, and if it suddenly stopped
working, I'd have a lot of fixing to do.)
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
|> On 25 Apr 2002 04:12:30 -0400, "Mathias Nord"
|> <mathi...@hotmail.com> wrote:
|> >Consider the following:
|> >struct Test
|> >{
|> > static const char* name()
|> > {
|> > return "XYZ";
|> > }
|> > static const char* name2()
|> > {
|> > static const char n[] = "XYZ";
|> > return n;
|> > }
|> >};
|> >I know (?) that Test::name2() is both legal and portable but
|> >Test::name() seems to work too. At least with VC++7 and some old
|> >version of gcc.
|> >The question: Is Test::name() legal?
|> Quite the contrary. Let me be a little pedantic, but I think it's
|> important to help understanding here. String-literals are not
|> objects,
They most certainly are, although they are unnamed objects.
|> they are expressions that designate objects (therefore it's quite
|> improper to say "address of a string literal" :) Note BTW that they
|> are the only kind of literal that are l-values).
And anything which is an l-value must be an object, since its address
can be taken.
|> The object a string literal refers to (an array of const char or
|> const wchar_t) has always static duration (2.13.4).
More correctly, the string literal defines an unnamed array (an
object) of const char, with static duration, as you say. The length of
the array can be detected by such tricks as passing it to a template
function with a parameter char const (&x)[N], where N is a template
parameter.
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
Legal by (2.13.4):
"A[n]... string literal has ... static storage duration (3.7) "
HTH,
--
Michiel Salters
> > static const char* name2()
> > {
> > static const char n[] = "XYZ";
^^^
so the answer is that both implementations are correct, sorry for my
oversight :(
Bob.
>Gennaro Prota <gennar...@yahoo.com> writes:
>
>|> String-literals are not objects,
>
>They most certainly are, although they are unnamed objects.
>
>|> they are expressions that designate objects (therefore it's quite
>|> improper to say "address of a string literal" :) Note BTW that they
>|> are the only kind of literal that are l-values).
>
>And anything which is an l-value must be an object, since its address
>can be taken.
An l-value is an expression to me (3.10p1). It *refers* to an object,
is not a C++ object by itself.
>|> The object a string literal refers to (an array of const char or
>|> const wchar_t) has always static duration (2.13.4).
>
>More correctly, the string literal defines an unnamed array (an
>object) of const char, with static duration, as you say.
Yes, the array is unnamed (the string-literal itself is not an
identifier, so its use is not a name) but in what does this differ
from what I said? The only difference I can detect depends on your
wording "the string literal defines", but you are not saying that the
use of a string literal is a definition, are you? (And BTW you first
say it is an object then that it *defines* an object, so I can't see
your point)
I'm quite surprised by this reply, since I consider you one of my
teachers here :(((
Genny.
What you write is true -- n[] is an array initialized by a string
literal. However, you imply that name2() is not legal because it
returns the address of a local variable. n[] is declared static,
so name2() is legal.
However, your point that name() returns the data directly while
name2() has to copy it the first time it's called, is perfectly true.
This also implies that name2() could have returned a non-const
pointer -- and if it did, the caller could have modified the data in
n[]. This would be illegal for name(), although I believe that no
diagnostic is required.
Well, since it is unnamed...:
According to K&R II (page 197): [1]
"An _object_ is a named region of storage; an _lvalue_ is an
expression referring to an object."
So it cannot be unnamed, to be an lvalue...
Attila
|> On 25 Apr 2002 16:41:12 -0400, James Kanze <ka...@alex.gabi-soft.de>
|> wrote:
|> >Gennaro Prota <gennar...@yahoo.com> writes:
|> >|> String-literals are not objects,
|> >They most certainly are, although they are unnamed objects.
|> >|> they are expressions that designate objects (therefore it's
|> >|> quite improper to say "address of a string literal" :) Note
|> >|> BTW that they are the only kind of literal that are l-values).
|> >And anything which is an l-value must be an object, since its
|> >address can be taken.
|> An l-value is an expression to me (3.10p1). It *refers* to an
|> object, is not a C++ object by itself.
Right. I seem to have skipped a few steps. A string literal causes
an object to be created, and refers to that object.
I think what bothered me was the bald statement that they are not
objects, and that it is improper to speak of their address. While the
string literal itself is not formally an object, it is quite usual (I
think) to use the term to refer to the actual object it causes to be
created, and I, for one, do talk about the address of string literals.
And of course, the expression &"abc", is legal, and has the type
"pointer to array[4] of const char".
|> >|> The object a string literal refers to (an array of const char
|> >|> or const wchar_t) has always static duration (2.13.4).
|> >More correctly, the string literal defines an unnamed array (an
|> >object) of const char, with static duration, as you say.
|> Yes, the array is unnamed (the string-literal itself is not an
|> identifier, so its use is not a name) but in what does this differ
|> from what I said? The only difference I can detect depends on your
|> wording "the string literal defines", but you are not saying that
|> the use of a string literal is a definition, are you? (And BTW you
|> first say it is an object then that it *defines* an object, so I
|> can't see your point)
Careless wording?
I found your first paragraph misleading, since there very definitly is
an object involved, with an implicit definition, static memory
allocation, an address, etc. But perhaps I just read it wrong.
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
|> James Kanze wrote:
|> [SNIP]
|> > |> they are expressions that designate objects (therefore it's
|> > |> quite improper to say "address of a string literal" :) Note
|> > |> BTW that they are the only kind of literal that are
|> > |> l-values).
|> > And anything which is an l-value must be an object, since its
|> > address can be taken.
|> Well, since it is unnamed...:
|> According to K&R II (page 197): [1]
|> "An _object_ is a named region of storage; an _lvalue_ is an
|> expression referring to an object."
|> So it cannot be unnamed, to be an lvalue...
According to the standard (5.1/2): "A string literal is an lvalue; all
other literals are rvalues." In C (which is the language K&R write
about), we also have (6.5.1/4) "A string literal is a primary
expression. It is an lvalue with type as detailed in 6.4.5."
Standardese is sometimes difficult to understand, but I don't see how
these phrases could possibly cause a problem. And string literals
definitly don't refer to named objects.
I suspect that Kernighan and Richie just overlooked the case.
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
> A string literal causes an object to be created, and refers to that object.
Not necessarily every literal I think: due to 2.13.4p2 a compiler can
reuse (part of) an object already created for another literal. Do you
agree?
>I found your first paragraph misleading, since there very definitly is
>an object involved, with an implicit definition, static memory
>allocation, an address, etc. But perhaps I just read it wrong.
In fact, my intent was exactly to reassure the original poster that
*there is* an object somewhere even if it isn't explictly declared in
his code and that, therefore, the situation is (thanks to 2.13.4 and
5.1p2) completely different from, let's say:
const int& f() { return 3; }
Genny.
|> On 27 Apr 2002 07:51:32 -0400, James Kanze <ka...@alex.gabi-soft.de>
|> wrote:
|> > A string literal causes an object to be created, and refers to
|> > that object.
|> Not necessarily every literal I think: due to 2.13.4p2 a compiler
|> can reuse (part of) an object already created for another literal.
|> Do you agree?
Yes. But there is still an object.
--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]