Постоянный адрес строки - PullRequest
       4

Постоянный адрес строки

6 голосов
/ 23 октября 2009

В моей программе несколько идентичных строковых констант:

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

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

Есть ли гарантия, что они имеют один и тот же адрес, то есть я могу написать следующий код? Я слышал, что GNU C ++ оптимизирует строки, чтобы они имели одинаковый адрес. Могу ли я использовать эту функцию в своих программах?

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

Ответы [ 6 ]

11 голосов
/ 23 октября 2009

Конечно, нет гарантии, но это обычная (я думаю) оптимизация.

Стандарт C ++ гласит (2.13.4 / 2 "Строковые литералы):

Является ли все строковые литералы различными (то есть хранятся ли они в неперекрывающихся объектах), определяется реализацией.

Чтобы быть ясным, вы не должны писать код, который предполагает, что эта оптимизация будет иметь место - как говорит Крис Латс, код C ++, который опирается на это, - это код, который ждет, чтобы быть сломанным.

8 голосов
/ 23 октября 2009

это называется строка интернирования

В вашем случае лучше не полагаться на это. Возможности разные, но я не очень компетентен в этом вопросе

3 голосов
/ 23 октября 2009

GCC использует такую ​​оптимизацию, а Microsoft - (они называют это объединение строк ). Это просто оптимизация, C ++ Standard прямо заявляет, что вы не можете использовать это (в 2.13.4 / 2). Кроме того, просто представьте, что вы получите указатель на строку из какого-то другого модуля / библиотеки - я не думаю, что компилятор может выполнить такую ​​оптимизацию в этом случае.

2 голосов
/ 23 октября 2009

Там нет такой гарантии. Язык просто говорит, что они могут иметь одинаковый адрес. Или нет.

2 голосов
/ 23 октября 2009

Есть ли гарантия, что они имеют один и тот же адрес, то есть я могу написать следующий код?

Стандарт допускает такую ​​оптимизацию, поскольку строковые литералы доступны только для чтения.

Я слышал, что GNU C ++ оптимизирует строки, чтобы они имели одинаковый адрес. Могу ли я использовать эту функцию в своих программах?

Да, GCC / G ++ часто делают это. AFAIK, есть возможность включить / выключить это.

0 голосов
/ 23 октября 2009

На самом деле, есть решение, настолько простое решение:

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;
}

Вы не можете сравнивать два разных строковых литерала, но используйте глобальную переменную const, чтобы передать ваше значение, и OK для сравнения адреса памяти:)

Может быть, пропал какой-то экстерьер ... У меня есть некоторые трудности с этим зверем

...