Объем (струнных) литералов
Я всегда стараюсь не возвращать строковые литералы, потому что я боюсь, что они не определены вне функции. Но я не уверен, что это так. Возьмем, например, эту функцию:
const char *
return_a_string(void)
{
return "blah";
}
Это правильный код? Он работает для меня, но, возможно, он работает только для моего компилятора (gcc). Итак, вопрос в том, имеют ли (string) литералы рамки или они присутствуют/определены все время.
Ответы
Ответ 1
Этот код отлично подходит для всех платформ. Строка компилируется в двоичный файл как статический строковый литерал. Если вы работаете с окнами, вы даже можете открыть свой .exe с помощью блокнота и выполнить поиск самой строки.
Поскольку это статическая строковая буква, не имеет значения.
Объединение строк:
Одна вещь, которую нужно обратить внимание, заключается в том, что в некоторых случаях идентичные строковые литералы могут быть "объединены", чтобы сэкономить место в исполняемом файле. В этом случае каждый строковый литерал, который был таким же, мог иметь одинаковый адрес памяти. Вы никогда не должны предполагать, что это будет или не будет иметь место.
В большинстве компиляторов вы можете установить, следует ли использовать статический пул строк для литералов-стимуляторов.
Максимальный размер строковых литералов:
Несколько компиляторов имеют максимальный размер для строкового литерала. Например, с VС++ это примерно 2048 байт.
Изменение строкового литерала дает поведение undefined:
Изменение строкового литерала никогда не должно выполняться. Он имеет поведение undefined.
char * sz = "this is a test";
sz[0] = 'T'; //<--- undefined results
Широкие строковые литералы:
Все вышеизложенное применимо в равной степени к широким строковым литералам.
Пример: L "это широкий строковый литерал";
Стандарт С++: (раздел lex.string)
1 Строковый литерал представляет собой последовательность символов (как определено в lex.ccon), окруженный двойными кавычками, необязательно, начиная с буква L, как в "..." или "L "...". Строковый литерал, который не начинается с L - обычный строковый литерал, также называемый узким строковый литерал. Обычный строковый литерал имеет тип "массив из n Const char "и статической продолжительности хранения (basic.stc), где n - размер строки, как определено ниже, и инициализируется данным персонажи. Строковый литерал, начинающийся с L, такой как L" asdf ", является широкий строковый литерал. Широкий строковый литерал имеет тип" массив N const wchar_t "и имеет статическую продолжительность хранения, где n - размер из строка, как определено ниже, и инициализируется с заданным символом Ослабляет.
2 Независимы ли все строковые литералы (то есть, хранятся в неперекрывающиеся объекты) определяется реализацией. Эффект из попытка изменить строковый литерал undefined.
Ответ 2
Я приведу вам пример, чтобы ваше замешательство стало несколько ясным.
char *f()
{
char a[]="SUMIT";
return a;
}
это не работает.
но
char *f()
{
char *a="SUMIT";
return a;
}
это работает.
Причина: "СУММА" - это литерал, имеющий глобальную область действия.
в то время как массив, который является просто последовательностью символов {'S', 'U', 'M', 'I', "T ''\0 '}
имеет ограниченный объем, и он исчезает, как только возвращается программа.
Надеюсь, что это поможет
Ответ 3
Да, это хорошо. Они живут в глобальной таблице строк.
Ответ 4
Нет, строковые литералы не имеют области видимости, поэтому ваш код гарантированно работает во всех платформах и компиляторах. Они хранятся в двоичном образе программы, поэтому вы всегда можете получить к ним доступ. Однако попытка написать им (отбрасывая const
) приведет к поведению undefined.
Ответ 5
Это справедливо в C (или С++), как объяснили другие.
Единственное, что я могу думать, чтобы следить за тем, что, если вы используете DLL, то указатель не останется действительным, если dll, содержащий этот код, будет выгружен.
Стандарт C (или С++) не понимает или не учитывает загрузку и выгрузку кода во время выполнения, поэтому все, что делает это, будет иметь последствия, связанные с реализацией: в этом случае следствием является то, что строковый литерал, который является который должен иметь статическую продолжительность хранения, появляется из POV вызывающего кода, чтобы он не сохранялся в течение всей продолжительности программы.
Ответ 6
Фактически вы возвращаете указатель на строку с нулевым завершением, хранящуюся в разделе данных исполняемого файла, область, загружаемую при загрузке программы. Просто не пытайтесь изменить персонажей, это может дать непредсказуемые результаты...
Ответ 7
Очень важно отметить результаты undefined, о которых говорил Брайан. Поскольку вы объявили функцию как возвращающую тип const char *, вы должны быть в порядке, но на многих платформах строковые литералы помещаются в сегмент только для чтения в исполняемом файле (обычно в текстовом сегменте) и изменяя их, нарушение доступа на большинстве платформ.