在c ++中存储文字常量

inf*_*oop 4 c++

我想知道文字常量实际存储在内存中的哪个位置?

例:

int i = 5;
char* data = char* &("abcdefgh");
Run Code Online (Sandbox Code Playgroud)

存储部分idata取决于它们的声明位置.但编译器是否存储5"abcdefgh"在将其实际复制到变量之前?

在这里我可以得到"abcdefgh"它存储位置的地址,但为什么我不能得到它的地址5

小智 10

整数文字5可以是机器指令的一部分.例如:

 LD A, 5
Run Code Online (Sandbox Code Playgroud)

将值5加载到处理器寄存器A中用于某种虚构架构,并且因为5实际上是指令的一部分,所以它没有地址.很少(如果有的话)架构能够在机器指令中内联创建字符串文字,因此这些架构必须实际存储在内存中的其他地方并通过指针访问.C++标准没有规定"其他地方"的确切位置.


Mat*_*lia 6

在语言层面上,字符串文字和数字文字是不同的野兽.

C和C++标准基本上指定字符串文字被视为"好像"您定义了具有适当大小和内容的常量字符数组,然后使用其名称代替文字.IOW,当你写的时候

const char *foo = "hello";
Run Code Online (Sandbox Code Playgroud)

这是因为,如果你写

// in global scope
const hello_literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'};

...
const char *foo = hello_literal;
Run Code Online (Sandbox Code Playgroud)

(有一些向后兼容的异常允许你甚至写char *foo = "hello";,没有const,但是已经弃用了,并且无论如何都试图通过这样的指针写入未定义的行为)

所以,鉴于这种等价,你可以拥有字符串文字的地址是正常的.整数文字OTOH是rvalues,标准规定你不能使用任何地址 - 你可以粗略地认为它们是标准期望在传统意义上没有后备存储器位置的值.


现在,这种区别实际上源于这样一个事实:在机器级别它们通常以不同的方式实现.

字符串文字通常作为数据存储在内存中的某个位置,通常位于只读数据部分中,该部分直接从可执行文件映射到内存中.当编译器需要它的地址时,它很容易被强制,因为它是已经在内存中的数据内容,因此它确实有一个地址.

相反,当你做某事时

int a = 5;
Run Code Online (Sandbox Code Playgroud)

5并没有真正有象一个单独的存储器位置"hello world"以上阵列,但它通常是嵌入到机器代码作为立即值.

有一个指向它的指针是相当复杂的,因为它指向一个指令中途的指针,并且通常以不同于int您可以指向的常规变量的预期格式指向数据- 认为x86在哪里为使用更紧凑编码的小数字,或PowerPC/ARM和其他RISC架构,其中一些值是由隐式桶形移位器操作的立即构建的,你甚至不能为某些值提供立即 - 你必须用几条指令组成它们,或哈佛架构,其中数据和代码存在于不同的地址空间中.

因此,您不能获取数字文字的地址(以及数字表达式评估结果和许多其他临时内容); 如果你想拥有一个数字的地址,你必须先将它分配给一个变量(它可以提供一个内存存储),然后询问它的地址.


Tho*_*ews 5

尽管 C 和 C++ 标准没有规定文字的存储位置,但通常的做法是将它们存储在两个位置之一:代码中(请参阅@NeilButterworth 答案)或“常量”段中。

常见的可执行文件有代码部分和数据部分。数据段可以分为只读、未初始化读/写和初始化读/写。通常,文字被放入可执行文件的只读部分。

某些工具还可以将文字放入单独的数据文件中。该数据文件可用于将数据编程到只读存储设备(ROM、PROM、闪存等)中。

总之,文字的放置取决于实现。C 和 C++ 标准规定,写入文字位置是未定义的行为。使用字符文字的首选做法是声明变量,以便const编译器在写入文字时可以生成警告或错误。