编译器如何区分 C++ 中不同类中具有相同名称的静态数据成员?

发布于 2024-09-26 00:57:16 字数 188 浏览 4 评论 0原文

我最近参加了一次 C++ 面试,被问到编译器如何区分两个不同类中具有相同名称的静态数据成员?

由于所有静态数据变量都存储在数据段中,因此编译器必须有一种方法来跟踪哪些静态数据属于哪个类,特别是当它们具有相同名称时。

编辑: 我回答了name mangling,但他拒绝了,说name mangling只在同一个班级的成员之间使用。

I had a C++ interview recently where I was asked, how does the compiler differentiate static data members having the same name in two different classes?

Since all static data variables are stored in the data segment, there has to be a way by which the compiler keeps track of which static data belongs to which class especially when they have the same name.

Edit:
I answered name mangling, but he refused saying name mangling is used only among the members of the same class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

迷鸟归林 2024-10-03 00:57:17

名称只是人类用来赋予事物意义的东西。

一旦编译器知道它们是不同的项目(因为它们在不同的类中声明),它就不会使用名称来区分二进制文件中的它们,它将使用指针,并且指针不关心名称:)

然后就没有什么禁止的了在数据名称前面加上封闭类..

A name is just something that is used by humans to give a meaning to things.

Once that the compiler knows that they are different items (since they are declared in different classes) it won't use the name to distinguish them inside the binary, it will use pointers and pointers don't care about names :)

Then nothing forbids from prepending the name of the data with the enclosing class..

宣告ˉ结束 2024-10-03 00:57:17

所有“名称修改”答案都解决了调试器如何找到每个符号的存储以及链接器如何知道差异,但编译器知道,因为这些实体占用符号表中的不同条目

就是这样。

可执行文件根本不需要知道有关名称的任何信息{*}。只是地点。编译器知道名称,并且该知识被编码在符号表中(但是可以实现)。

{*} 好吧,无论如何,在没有 RTTI 的情况下。

All the "name mangling" answer address how the debugger finds the storage for each symbol and how the linker knows the difference, but the compiler knows because these entities occupy different entries in the symbol table.

That's it.

The executable doesn't need to know anything about names at all{*}. Just locations. The compiler knows about names, and that knowledge is coded in the symbol table (however it may be implemented).

{*} Well, in the absence of RTTI, anyway.

谢绝鈎搭 2024-10-03 00:57:17

类的名称限定了成员的名称:myclass::mymemb。当从类外部引用它们时,编译器以与您相同的方式区分它们。

在实现中,这是通过名称修改来完成的;编译器对类的名称和成员的名称进行 santizes,并将它们连接在一起形成混乱,例如 __i_7myclass_6mymemb

名称修饰过程(或其必要性)是我们需要 extern "C" 来与定义非修饰名称的 C 接口兼容的原因。

The name of the class qualifies the name of the member: myclass::mymemb. The compiler differentiates them the same way you do, when referring to them from outside the class.

Within the implementation, this is done by name mangling; the compiler santizes the name of the class and the name of the member, and catenates them together into a mess such as __i_7myclass_6mymemb.

The name mangling process (or its necessity) is the reason why we need extern "C" for compatibility with C interfaces, which define non-mangled names.

梦毁影碎の 2024-10-03 00:57:17

类的静态成员的名称将被修改,以便类名成为链接器看到的“全局”名称的一部分。

static members of a class will have their names mangled such that the class name is part of the 'global' name seen by the linker.

凉栀 2024-10-03 00:57:17

它将类名称附加到数据成员名称。 (然后对整个事情进行命名。)

It attaches the class name to the data member name. (And then name-mangles the whole thing.)

花桑 2024-10-03 00:57:16

这些名字与他们的班级名称混合在一起。 的示例

class A {
  static int i;
};

int A::i = 0;

clang 编译器输出

$ clang++ -cc1 -emit-llvm main1.cpp -o -
; ModuleID = 'main1.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"

@_ZN1A1iE = global i32 0, align 4

,其中 _ZN1A1iE

$ c++filt _ZN1A1iE
A::i

The names are mangled with their class name in them. An example with the clang compiler

class A {
  static int i;
};

int A::i = 0;

Output

$ clang++ -cc1 -emit-llvm main1.cpp -o -
; ModuleID = 'main1.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"

@_ZN1A1iE = global i32 0, align 4

Where _ZN1A1iE is

$ c++filt _ZN1A1iE
A::i
耀眼的星火 2024-10-03 00:57:16

它是实现定义的,因此没有一种方法必须完成。

不过,名称修改很常用。

It's implementation-defined, so there's no one way it has to be done.

Name mangling is commonly used though.

小清晰的声音 2024-10-03 00:57:16

好吧,我假设通过名称修改,类的名称也用数据进行编码。如果它像前缀名称一样简单,我不会感到惊讶:

class one
{
   static int data;
};

class two
{
   static int data;
};

包含名称

one::data
two::data

可以在数据段中 。这些都是独特的名字。

Well I would assume that through name mangling the name of the class is encoded with the data too. I wouldn't be surprised if it's as simple as prefixing the name:

class one
{
   static int data;
};

class two
{
   static int data;
};

could have the names

one::data
two::data

in the data segment. Those are unique names.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文