我花了很多时间学习TOC和编译器设计,但尚未完成,但我对这些概念感到满意。另一方面,我对汇编和机器代码的知识非常浅薄,而且我总是希望/需要连接双方(代码的HLL和LLL表示),因为我正在学习C ++而非常注重绩效和优化讨论。
C ++是一种静态类型语言:
我的问题是:我们的变量在代码语句中作为表达式编写时,所有这些变量(以及带有标识符的其他实体)都会在运行时变为运行,仅仅是寻址到虚拟内存位置的指令(对于静态和for globals)和寻址与局部变量的堆栈地址相关吗?
我的意思是,在成功编译包括语义和语法验证之后,在运行时处理数据作为目标内存字节的保证实体而不考虑任何标识符或任何检查是不明智的,不再需要符号表?
如果我的问题似乎是由于缺乏学习努力而导致的问题类型(我希望不会这样做),请告诉我这个问题,并告诉我在哪里阅读。如果是这样,那么老实说,因为我现在专注于C ++并且还没有机会对低级语言有充分的了解,我提前为此道歉。
答案 0 :(得分:3)
你发现了。一旦编译成机器代码,就不再有任何变量标识符(或变量类型)的概念。它只是某个位置的字节。 编译器(编译时)基于变量名确定了哪个位置,或者在全局变量的情况下由链接器(链接时)确定。
当然,为了调试目的,保留标识符等信息会很有用。这正是"编译调试信息"意味着:当您这样做时,编译器将以某种方式将(冗余)标识符嵌入到生成的代码中,以便调试器可以访问它们。或者将它们放在一个单独的文件中;具体细节取决于调试信息的格式。
答案 1 :(得分:2)
是的,主要是。有一些细节会使标识符不仅仅是地址或堆栈偏移。
首先我们在C ++中使用RTTI,这意味着在运行时期间,至少类型的名称仍然可用。例如:
const std::type_info &info = typeid(*ptr_interface);
std::cout << info.name() << std::endl;
将打印*ptr_interface
所属类型的名称。
其次,由于程序的链接方式,来自目标文件的符号可能仍然存在于执行图像中。例如,Linux内核使用它,因为它可以产生包括函数名称的堆栈的回溯。它还使用函数名称的知识,以便能够加载和链接模块。 Gnu C库中存在类似的功能,与链接时相比,它能够在堆栈跟踪中检索函数名称。
在正常情况下,虽然代码不会受到变量原始名称的影响(但编译器当然会发出适合变量类型的代码)。