【问题标题】:The memory address of constants in CC中常量的内存地址
【发布时间】:2021-01-05 23:35:02
【问题描述】:

我正在学习 C 中的指针,我有几个问题。 下面是一段代码,仅供参考。

int var = 300;
char s[] = "Clang";
char *p  = "Wonder";

我知道所有变量在内存中都有它们的地址。 varsp 等变量在内存中有自己的地址。

但我想知道常量是否也有内存地址。

300,"Clang","Wonder"自己有内存地址吗?

【问题讨论】:

  • 300 不是对象:它没有地址; "Clang" nd "Wonder" 两者本身都是对象(类型数组分别为 6 和 7 字符)并有自己的地址。 您将"Wonder" 的地址复制到您的代码中的p
  • C 标准描述了一种计算模型,用于指定程序的行为方式。在该模型中,常量300 不是对象并且没有地址,而字符串会导致创建静态数组,它们是对象并且确实具有地址。然而,C 标准并不要求实现完全遵循模型。他们可能会优化程序并生成不同的代码,只要程序的可观察行为(例如其输出)相同……
  • ... 如果编译器可以在没有它的情况下初始化s(可能通过在指令中使用立即操作数)或者可以从至少在某种程度上编程。 "Wonder" 不太可能被删除,但这取决于p 的使用方式。
  • sp 之间的另一个区别是,所有(除了少数例外)"Wonder" 将存储在.rodata 部分中并且不能修改。因此"Wonder" 中的字符不能被修改。使用s"Clang"只是用来初始化一个正则数组,可以修改s的内容。

标签: c pointers memory constants memory-address


【解决方案1】:

只有对象和函数在 C 中具有地址。命名变量是对象。单独使用的字符串文字 "Wonder" 是一个对象,一个由 7 个字符组成的数组(即 char[7]) - 6 个可见字符和终止空字符 - 因此可能有一个地址。文字 "Clang" 在这里是一个边界情况,严格来说它没有地址,因为它不是一个对象,而只是一个特殊的初始化语法。

C 模型与 Python 编程语言完全不同,其中

a = 300

a 是一个没有地址的名称,而300 是一个有地址的对象。

可能是因为虽然 C 说一个对象或函数有一个地址,但许多编译器优化代码,创建一个不遵循严格的 C 抽象机的可执行文件;因此,一个对象只有在你观察到它时才可能有一个地址。

【讨论】:

  • Re“严格来说它没有地址”:严格来说它确实有地址,在优化之前的C模型中。 C 标准明确表示,源文本中的字符串文字用于定义具有指示内容的静态数组,即使它用于初始化另一个数组。
  • "Wonder" 是一个 7 个字符的数组,只是说,更惯用的说法是:"Wonder" 的类型为 /*read-only*/char[7]
  • @pmg oops :)) 我最初的回答让我很困惑,但数字 6 仍然存在。
【解决方案2】:

变量和常量的内存使用是编译器实现的问题。在实践中,常量定义如下:

const *foo = "bar";
const int answer = 42;

通常会占用内存并有地址。也就是说,在运行时程序地址空间的某个位置,您会发现代表文本“条”的字节序列和代表数字 42 的字节序列。

但是,由于现代编译器进行了积极的优化,一些常量可能根本不存在运行时是合理的。例如,在这样的 sn-p 中:

const int foo = 3;
int x = foo * 4;

可以想象,如果 foo 从未在其他任何地方使用过,编译器可能(实际上)将其转换为:

int x = 12;

foo 在运行时甚至都不存在。

顺便说一句,许多开发人员将 C 预处理器宏视为“常量”:

#define PI 3.14159

这些通常在运行时不占用内存,因为它们在编译时被替换到代码中。

【讨论】:

  • 这并没有完全解决值 300 是否有地址的问题。
  • 我认为现在可以。但是对于这样的问题,可能会如此珍贵,以至于您最终得到的答案只有编译器设计者才能理解;)
【解决方案3】:

大多数实现将对象放在通常称为 .text(代码)、.data - 初始化数据、.bss - 归零数据、.rodata - 只读数据的“部分”中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多