C++ 在一天结束时,变量标识符是完全不必要的吗?

C++ 在一天结束时,变量标识符是完全不必要的吗?,c++,compilation,machine-code,executable-format,C++,Compilation,Machine Code,Executable Format,我花了很长时间学习TOC和编译器设计,虽然还没有完成,但我对这些概念感到满意。另一方面,我对汇编和机器代码有很深的了解,而且我总是希望/需要连接两个方面(代码的HLL和LLL表示),因为我正在学习C++,非常注重性能和优化讨论。 C++是一种静态类型语言: 我的问题是:当我们的变量作为表达式写入代码语句中时,所有这些变量(以及其他具有标识符的实体)是否在运行时都变成了虚拟内存位置的寻址指令(对于静态和全局变量)以及与局部变量堆栈地址相关的寻址指令 我的意思是,在成功编译(包括语义和语法验证)之后

我花了很长时间学习TOC和编译器设计,虽然还没有完成,但我对这些概念感到满意。另一方面,我对汇编和机器代码有很深的了解,而且我总是希望/需要连接两个方面(代码的HLL和LLL表示),因为我正在学习C++,非常注重性能和优化讨论。 C++是一种静态类型语言:

我的问题是:当我们的变量作为表达式写入代码语句中时,所有这些变量(以及其他具有标识符的实体)是否在运行时都变成了虚拟内存位置的寻址指令(对于静态和全局变量)以及与局部变量堆栈地址相关的寻址指令

我的意思是,在成功编译(包括语义和语法验证)之后,在不考虑任何标识符或任何检查的情况下,在运行时将数据作为目标内存字节的保证实体来处理,而不再需要符号表,这难道不明智吗


如果我的问题似乎是由于缺乏学习努力(我希望不是),请告诉我,并告诉我在哪里阅读。如果是这样的话,那就老实说,因为我现在集中精力在C++上,还没有机会掌握低级语言的知识,我对此表示道歉。

< P>你是在现场。一旦编译成机器代码,就不再有任何变量标识符(或者变量类型)的概念。它只是某个位置的字节。哪个位置是由编译器(编译时)根据变量名确定的,或者是由链接器(链接时)在全局变量的情况下确定的


当然,为调试目的保留标识符等信息可能会很有用。这正是“使用调试信息进行编译”的意思:当您这样做时,编译器将以某种方式将(冗余)标识符嵌入到生成的代码中,以便调试器可以访问它们。或者把它们放在一个单独的文件中;详细信息取决于调试信息的格式。

是的,大部分情况下。有一些细节将使标识符不仅仅停留在地址或堆栈偏移量上

首先,我们在C++中使用了RTTI,这意味着在运行时,至少类型的名称仍然可用。例如:

const std::type_info &info = typeid(*ptr_interface);
std::cout << info.name() << std::endl;
const std::type_info&info=typeid(*ptr_接口);

这就是没有内省或反射的静态编译语言的工作原理。编译C++源文件时,编译器生成的对象文件没有引用源中的变量。这是所有的内存位置。是的,你的理解是正确的。@ Deutl uccg,C++不包括C语言。具体而言,禁止枚举类型之间的隐式转换,不同指针类型之间的隐式转换也是如此。@DieterLücking使用静态类型语言来构建动态类型行为并不意味着该语言不是静态类型的typed@DieterL吕克:我不知道printf是如何证明C不是静态类型的例子。也许我们使用了不同的定义。谢谢你的澄清。比如说,对于普通代码x=y+1中访问l值或r值的简单变量,在运行时,访问表达式的变量将作为未选中标识符或类型的寻址指令。请注意,RTI是一个可以被编译器打开和打开的特性,它会给程序增加额外的开销。@内科医生,好的,机器代码本身将使用适当的宽寄存器/对齐来访问分配给变量的内存,但是它并没有天生地关心C++代码的样子。如果这最终是你的问题。当然,它并不关心变量的名称。@你似乎混淆了一些事情,尽管很难说清楚具体是什么——像“int x=y+1”这样的表达式在任何类型的表中出现的唯一时间是,如果y被定义为外部变量,例如在共享库中。否则,生成的代码可能只是类似于“add%rax,$1”。我鼓励您编译一些简单的语句,看看生成的汇编代码。这是一个坏主意,这就是为什么它没有发生。我不知道为什么你会觉得所有这些含糊的思考都是必要的,正如Benno所说,你可以简单地编译一个程序(具有渐进的优化级别),并自己看看典型的C++实现。