views:

155

answers:

6

I have several identical string constants in my program:

const char* Ok()
{
  return "Ok";  
}

int main()
{
  const char* ok = "Ok";
}

Is there guarantee that they are have the same address, i.e. could I write the following code? I heard that GNU C++ optimize strings so they have the same address, could I use that feature in my programs?

int main()
{
  const char* ok = "Ok";
  if ( ok == Ok() ) // is it ok?
  ;
}
+11  A: 

There's certainly no guarantee, but it is a common (I think) optimization.

The C++ standard says (2.13.4/2 "String literals):

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-defined.

To be clear, you shouldn't write code that assumes this optimization will take place - as Chris Lutz says, C++ code that relies on this is code that's waiting to be broken.

Michael Burr
There nothing more to say.
big-z
+8  A: 

this is called string interning

In you case it is better not to rely on that. The scopes are different, but I don't find myself very competent on this subject

Svetlozar Angelov
+1 Any code that relies on this is waiting to be broken.
Chris Lutz
The notion of "scope" is completely irrelevant here. "Scope" applies to names of entities. String literals have no names, so the notion of "scope" doesn't apply to them.
AndreyT
+2  A: 

Is there guarantee that they are have the same address, i.e. could I write the following code?

The standard allows such optimizations since string literals are read-only.

I heard that GNU C++ optimize strings so they have the same address, could I use that feature in my programs?

Yes, GCC/G++ often do that. AFAIK, there's an option to turn this on/off.

dirkgently
+2  A: 

There's no such guarantee. The language just says that they might have the same address. Or they might not.

AndreyT
+3  A: 

GCC uses such optimization, and Microsoft does (they call it string pooling). It is just optimization, C++ Standard explicitly states that you cannot use that (in 2.13.4/2). In addition, just imagine that you'll get pointer to string from some other module/library - I don't think compiler could make such optimization in that case.

Kirill V. Lyadvinsky
A: 

Actually, there is a solution, so simple solution:

char const * const Message_Ok = "OK";

char const * const OK() { return Message_Ok; }

int main(int argc, const char* argv[])
{
  if (OK() == Message_Ok) { std::cout << "OK" << std::endl; }
  return 0;
}

You cannot compare two different string literals, but use a const global variable to convey your meaning and it's OK to compare the memory address :)

Some extern may be missing... I've got some difficulty with that beast

Matthieu M.
Or OP could only use the OK function and not reduplicate the literal: `int main(){ const char* ok = OK(); if ( ok == Ok() ) ; }`
UncleBens
Yes, all in all, we just talking about variations on the DRY principle :)
Matthieu M.