2009-12-08 77 views
1

如果我调用一个函数,如 myObj.setType(“fluid”); 多次在一个程序中,多少个文字“流体”的副本被保存在内存中?编译器是否可以识别出这个文字已经被定义并且只是再次引用它?(c/C++)在文本部分做字符串文本共享内存的副本?

+1

如果你多次使用“流体”,也许你应该定义一个常量并引用常量而不是文字? – FrustratedWithFormsDesigner 2009-12-08 22:31:21

+1

如何编写一个小测试,通过比较不同文字指向的位置来检查这一点? – 2009-12-08 22:33:02

+1

呵呵,关于这个标题,很多链接器都会识别一个'.rodata',其中(例如)文字串属于。理论上'.text'应该保留给代码,尽管滥用是普遍的 - 也许是出于历史原因。 – 2009-12-08 22:41:08

回答

0

我相信,在C/C++没有该情况下,没有指定的处理,但在大多数情况下会使用该字符串的多个定义。

+0

该标准不要求或排除interned字符串。 Meyers谈论了Interceptor对象在_Effective C++ _中的问题(它实际上可能在_More Effective C++ _中)。 – KitsuneYMG 2009-12-09 04:39:34

15

这与C++(语言)无关。相反,它是编译器可以执行的“优化”。所以,答案,这取决于您使用的编译器/平台。

@大卫这是从latest draft of the language

§2.14.6(第28页)

是否所有字符串文字是 不同(即,存储在非 重叠对象)是 实现定义。试图修改字符串文字 的 的效果是undefined

重点是我的。

换句话说,C++中的字符串文字是不可变的,因为修改字符串文字是未定义的行为。所以,编译器是免费的,以消除多余的副本。

BTW,我只谈论C++)

+0

如今,字符串文字“重叠”是否是_unspecified_。 – 2017-05-25 19:00:33

4

是的,可以,但不能保证它会的。定义一个常数,如果你想确定。

+4

+1我会补充说“定义一个常量”意味着'const char cst [] =“foo”;'。 “定义”这个词可能会引起错误的想法。 – 2009-12-08 22:37:01

0

2.13.4/2:“是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的”。

这允许您所问的优化。

顺便说一句,可能存在一些含糊不清的情况,至少在标准的这一部分内是局部的。字符串常量的定义并不十分明确地告诉我下面的代码是否使用一个字符串字面量的两倍,或两个字符串字面量各一次:

const char *a = ""; 
const char *b = ""; 

但接下来的一段说:“在翻译阶段6个相邻窄字符串文字连接“。除非意思是说某些东西可以与自身相邻,否则我认为其意图非常清楚,该代码使用了两个字符串文字,它们在阶段6中连接在一起。因此,这不是一个字符串字面量的两倍:

const char *c = "a" "a"; 

不过,如果你读过“一”和“一个”是相同字符串字面量,那么标准要求你在谈论的最优化。但我不认为它们是相同的字面意思,我认为它们是不同的文字,恰好由相同的字符组成。这在标准的其他地方可能已经明确,例如在关于语法和解析的一般信息中。

无论是明确与否,许多编译器作家解释的标准,我认为它是这样的,所以我也可能是正确的;-)

1

这是一个编译器的实现问题。我用过的许多编译器都可以选择共享或合并重复的字符串文字。允许重复的字符串文字加快编译过程,但会产生更大的可执行文件。