是否保证相同内容字符串文字的存储相同? [英] Is storage for the same content string literals guaranteed to be the same?

查看:78
本文介绍了是否保证相同内容字符串文字的存储相同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码安全吗?编写与此类似的代码可能很诱人:

Is the code below safe? It might be tempting to write code akin to this:

#include <map>

const std::map<const char*, int> m = {
    {"text1", 1},
    {"text2", 2}
};

int main () {
    volatile const auto a = m.at("text1");
    return 0;
}

该映射仅可用于字符串文字.

The map is intended to be used with string literals only.

我认为这完全合法,并且似乎可以正常工作,但是我从来没有见过保证在两个不同地方使用的文字的指针是相同的.我无法使编译器为具有相同内容的文字生成两个单独的指针,所以我开始怀疑这个假设有多牢固.

I think it's perfectly legal and seems to be working, however I never saw a guarantee that the pointer for the literal used in two different places to be the same. I couldn't manage to make compiler generate two separate pointers for literals with the same content, so I started to wonder how firm the assumption is.

我只对内容相同的文字是否可以具有不同的指针感兴趣.或更正式地说,上面的代码可以吗?

I am only interested whether the literals with same content can have different pointers. Or more formally, can the code above except?

我知道有一种方法可以确保代码能正常工作,而且我认为上述方法很危险,因为编译器可以决定为文字分配两个不同的存储,特别是如果将它们放置在不同的翻译单元中时.我说的对吗?

I know that there's a way to write code to be sure it works, and I think above approach is dangerous because compiler could decide to assign two different storages for the literal, especially if they are placed in different translation units. Am I right?

推荐答案

标准不保证内容相同的字符串文字的地址相同.实际上, [lex.string]/16 说:

The Standard does not guarantee the addresses of string literals with the same content will be the same. In fact, [lex.string]/16 says:

所有字符串文字是否都不同(即存储在不重叠的对象中),并且未确定对 string-literal 的连续求值是产生相同对象还是不同对象.

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

第二部分甚至说当第二次调用包含字符串文字的函数时,您可能不会获得相同的地址!尽管我从未见过编译器能够做到这一点.

The second part even says you might not get the same address when a function containing a string literal is called a second time! Though I've never seen a compiler do that.

因此,在重复字符串文字时使用相同的字符数组对象是可选的编译器优化.通过安装g ++和默认的编译器标志,我还发现我在相同的翻译单元中为两个相同的字符串文字获得了相同的地址.但是正如您所猜测的,如果相同的字符串文字内容出现在不同的翻译单元中,我会得到不同的结果.

So using the same character array object when a string literal is repeated is an optional compiler optimization. With my installation of g++ and default compiler flags, I also find I get the same address for two identical string literals in the same translation unit. But as you guessed, I get different ones if the same string literal content appears in different translation units.

一个相关的有趣观点:不同的字符串文字也可以使用重叠数组.也就是说,给定

A related interesting point: it's also permitted for different string literals to use overlapping arrays. That is, given

const char* abcdef = "abcdef";
const char* def = "def";
const char* def0gh = "def\0gh";

您可能会发现abcdef+3defdef0gh都是相同的指针.

it's possible you might find abcdef+3, def, and def0gh are all the same pointer.

此外,有关重用或重叠字符串文字对象的规则仅适用于直接与文字相关联的未命名数组对象,如果文字立即分解为指针或绑定到数组的引用,则使用此规则.文字也可以用于初始化命名数组,如

Also, this rule about reusing or overlapping string literal objects applies only to the unnamed array object directly associated with the literal, used if the literal immediately decays to a pointer or is bound to a reference to array. A literal can also be used to initialize a named array, as in

const char a1[] = "XYZ";
const char a2[] = "XYZ";
const char a3[] = "Z";

这里,数组对象a1a2a3是使用文字初始化的,但是被认为与实际文字存储区分开(如果这种存储甚至存在)并且遵循普通的对象规则,因此存储这些数组将不会重叠.

Here the array objects a1, a2 and a3 are initialized using the literal, but are considered distinct from the actual literal storage (if such storage even exists) and follow the ordinary object rules, so the storage for those arrays will not overlap.

这篇关于是否保证相同内容字符串文字的存储相同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆