c – 相同内容字符串文字的存储是否保证相同?
作者:互联网
下面的代码安全吗?编写类似于此的代码可能很诱人:
#include <map>
const std::map<const char*, int> m = {
{"text1", 1},
{"text2", 2}
};
int main () {
volatile const auto a = m.at("text1");
return 0;
}
该映射仅用于字符串文字.
我认为它是完全合法的并且似乎正在工作,但是我从未看到保证在两个不同的地方使用的文字指针是相同的.我无法让编译器为具有相同内容的文字生成两个单独的指针,所以我开始怀疑这个假设是多么坚定.
我只对具有相同内容的文字是否可以有不同的指针感兴趣.或者更正式的,上面的代码可以除外吗?
我知道有一种方法来编写代码以确保它有效,我认为上面的方法很危险,因为编译器可以决定为文字分配两个不同的存储,特别是如果它们放在不同的翻译单元中.我对吗?
解决方法:
标准不保证具有相同内容的字符串文字的地址将是相同的.事实上,[lex.string]/16说:
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.
第二部分甚至说当第二次调用包含字符串文字的函数时,你可能得不到相同的地址!虽然我从未见过编译器那样做.
因此,在重复字符串文字时使用相同的字符数组对象是可选的编译器优化.通过安装g和默认编译器标志,我也发现在同一个翻译单元中我得到两个相同字符串文字的相同地址.但是正如您猜测的那样,如果相同的字符串文字内容出现在不同的翻译单元中,我会得到不同的内容.
一个相关的有趣点:它也允许不同的字符串文字使用重叠数组.也就是说,给定
const char* abcdef = "abcdef";
const char* def = "def";
const char* def0gh = "def\0gh";
你可能会发现abcdef 3,def和def0gh都是相同的指针.
此外,关于重用或重叠字符串文字对象的此规则仅适用于与文字直接关联的未命名数组对象,如果文字立即衰减到指针或绑定到对数组的引用,则使用该规则.文字也可用于初始化命名数组,如
const char a1[] = "XYZ";
const char a2[] = "XYZ";
const char a3[] = "Z";
这里使用文字对数组对象a1,a2和a3进行初始化,但被认为与实际文字存储不同(如果这样的存储甚至存在)并遵循普通对象规则,因此这些数组的存储不会重叠.
标签:c,language-lawyer,string-literals,storage 来源: https://codeday.me/bug/20191006/1860232.html