LINUX.ORG.RU

C: interning строковых констант


0

1

Народ, напомните, гарантирован ли interning строковых констант в С?

Только не надо говорить про конкретные компиляторы, хочется знать на уровне _стандарта_.

Например, если будет

#define foo «bar»

Гарантировано ли, что будет только одна копия строки в памяти - даже если я буду использовать foo несколько раз?

Желательно со ссылкой.

★★★★★

С каких пор препроцессор стал частью C? Ну и соответственно по новой строке на каждое использование.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

С каких пор препроцессор стал частью C?

Стандарт почитай.

Begemoth ★★★★★
()
Ответ на: комментарий от KblCb

Во-первых, давно. Во-вторых, препроцессор использован для показательности. Я могу много раз написать в коде «bar» «bar» «bar». Сколько их будет в памяти?

svu ★★★★★
() автор топика

Гарантировано ли, что будет только одна копия строки в памяти - даже если я буду использовать foo несколько раз?

Нет. ISO/IEC 9899:1999, раздел 6.4.5 параграфы 5 и 6.

The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. <поскипано> It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Ну и в Annex J. Undefined behaviour это также упомянуто.

Begemoth ★★★★★
()

Со ссылками затрудняюсь. Но.

bash$ cat main.c 
#include <stdio.h>

#define bar "barbarian"
#define foo(i) const char *s##i = bar;

foo(1);
foo(2);
foo(3);

int main () {
	foo(4);
	foo(5);

	printf ("%s\n%s\n%s\n%s\n%s\n", s1,s2,s3,s4,s5);
	return 0;
};

bash$ gcc main.c 

bash$ ./a.out 
barbarian
barbarian
barbarian
barbarian
barbarian

bash$ strings a.out
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
printf
__libc_start_main
GLIBC_2.0
PTRh0
0Y[]
[^_]
barbarian

bash$ gcc --version
gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
lodin ★★★★
()
Ответ на: комментарий от svu

Попробуйте скомпилировать и посмотреть, сколько раз будет встречаться foo в примере:

#include <stdio.h>
#include <string.h>
int main(){
char *a, b[] = "foo", *c = "foo";
printf("foo\n");
printf("%s, %s\n", b, c);
a = strdup("foo");
printf("%s\n", a);
c = strdup( b);
printf("%s\n", c);
}
(я не знаю, как сделать grep по бинарнику, strings не показывает «foo» ни одного раза)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от svu

Бегемот процитировал станадарт, но интересно, откуда это пошло. Предположу, что линкер вовсе не обязан объединять одинаковые строки из разных единиц компиляции.

И кстати — в с++, видимо из-за этой же фигни, строки нельзя использовать параметрами шаблона, что сильно досаждает.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Eddy_Em

grep -ao «foo»

strings по умолчанию игнорирует то, что короче 4-х символов (видимо, большая вероятность нарваться на случайную последовательность).

lodin ★★★★
()

> Народ, напомните, гарантирован ли interning строковых констант в С?

с99 не гарантирует, но разрешает компиляторам так поступать:

ISO/IEC 9899:1999

6.5.2.5 Compound literals

8 String literals, and compound literals with const-qualified types, need not designate distinct objects. (82)

________________________
(82) This allows implementations to share storage for string literals and constant compound literals with the same or overlapping representations.

arsi ★★★★★
()
Ответ на: комментарий от lodin

Тогда - да, один раз всего встречается. Ман читать было лень :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от arsi

Супер. Что б я делал без лора?

svu ★★★★★
() автор топика
Ответ на: комментарий от svu

А если не мультибайт?

Я так понимаю, что слово multibyte относится к sequence, а не к character.

Begemoth ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> И кстати — в с++, видимо из-за этой же фигни, строки нельзя использовать параметрами шаблона, что сильно досаждает.

В свеженьком стандарте можно template<char... S>, что не совсем строка, но весьма похоже.

const86 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.