【问题标题】:Besides the stated arguments and the "this" pointer, what other arguments does a c++ (g++) constructor get, in what order?除了声明的参数和“this”指针之外,c++ (g++) 构造函数还有哪些其他参数,以什么顺序?
【发布时间】:2018-11-06 19:30:19
【问题描述】:

我想从另一种语言调用 C++ 构造函数,并且需要知道要给它什么参数。我认为应该是陈述的论点和“this”指针。但是在 Gnu G++ 中,“this”指针是先出现还是最后出现?除了“this”指针还有其他隐藏的参数吗?

由于我已经解决了这些问题,因此此问题不涉及其他问题,例如名称错误。这个问题只是关于构造函数的参数。我使用的特定语言也不是问题,因为它是一种正在开发中的语言,而且这个问题一般适用于非 C++ 语言,而不仅仅是特定语言。

编辑添加:这是针对使用 G++ 约定的 Intel CPU。这应该回答了涉及 ABI 的问题。

至于“extern C”,这不是 C++ 代码。它调用C++代码,但由于它本身不是C++代码,所以使用“extern C”是没有意义的。此外,它调用的 C++ 代码必须按原样使用,而不能添加诸如“extern C”之类的东西。

我正在寻找的不是调用约定的确切正式定义。我只是想尝试一些线索。例如,C++ 编译器将“this”指针放在第一个参数以外的位置有多常见?除了“this”指针之外,还有其他隐藏的参数是多么普遍。如果“this”指针不是第一个,它几乎总是最后一个,还是有时在中间?等等。

【问题讨论】:

  • 您需要查看编译 C++ 代码的具体 ABI。
  • 没有从其他语言调用 C++ 构造函数的指定方法。对于语言互操作性,坚持使用 C。
  • 这是定义的实现。取决于编译器。取决于操作系统。取决于机器架构。没有一种方法可以做到。
  • @n.m.这不是句子所说的。 OP 似乎在说“外部语言不是 C,也不是 C++,因此 extern "C" 的建议没有帮助,因为我正在谈论的语言中不存在该设施/语法”
  • @LightnessRacesinOrbit 也许你是对的,改写我的回答以消除歧义。无论如何我想删除评论,因为我写了一个扩展版本作为答案。

标签: c++ constructor calling-convention abi


【解决方案1】:

this 指针在参数列表中的位置是实现定义的。如果您想与另一种语言交互,请添加 C 包装器:

// Your class
struct MyClass {
    MyClass(int, int);
    void doSomething(char,int);
};
// C wrapper
void* construct_MyClass(int a, int b) {
    return new MyClass(a, b);
}
void doSomething(void* thisPtr, char c, int a) {
    static_cast<MyClass*>(thisPtr)->doSomething(c, a);
}

这样,编译器会按照预期的顺序放置参数,让调用者代码与 C API 交互。您需要在 C 函数的声明中使用 use extern C 以保留 C 链接的名称。

【讨论】:

  • 我觉得你的回答应该提到 extern "C" 以及没有标准化 C++ ABI 的事实......
  • @JesperJuhl 如今,有标准化的 C++ ABI,大多数平台都选择了一个(并且只有一个)。但是这些并没有明确标准库的实现方式,因此它们的使用受到严格限制。
  • @Deduplicator 所以你所说的本质上是“没有标准化的 C++ ABI”.. 明白了。如果跨平台/编译器/架构/std lib 实现不同,那么就我而言,它不是标准化的 ABI。
  • @Deduplicator 什么标准ABI?
  • @JesperJuhl 如果你想要一个跨所有架构的 ABI,你需要一个虚拟机,比如 Java 或 .Net。但这还很遥远。
【解决方案2】:

C++ 标准没有定义如何将this 指针和任何参数传递给构造函数(或与此相关的任何函数)。这是 ABI(应用程序二进制接口)的工作,不同的编译器可以——并且在现实世界中——使用不同的 ABI。 ABI 不是 C++ 标准的一部分。

我将假设您要使用的两种语言都使用编译器编译为机器代码,因为这使讨论更容易。类似的原则适用于解释语言和其他语言,但具体细节有所不同。

一般来说,要从另一种语言正确调用任何 C++ 函数,两种语言必须由各自的语言编译器翻译成相同的 ABI,或者必须有一种定义/记录的方式,使两种不同的 ABI 可以互操作。换句话说,两个编译器——以及它们生成的机器代码——都必须设计成可以互操作。

实际上,C++ 标准指定了它如何在语言级别与 C 进行互操作。 C 不能使用所有 C++ 构造,但 extern "C" 函数是由 C++ 编译器构建的,允许从 C 调用它们。兼容的 C 和 C++ 编译器 - 或它们发出的代码 - 因此可以互操作,假设两者编译器支持相同的 ABI。例如,g++(gnu 的 C++ 编译器前端)和 gcc(gnu 的 C 编译器前端)被设计为可互操作,但它们并不(必然)与其他供应商的编译器互操作。从技术上讲,gnu C 编译器输出的机器代码可能与其他供应商的 C 编译器输出的代码互操作,但这样做需要非常详细地了解两种编译器支持的 ABI 是如何工作的(并且两者都有意支持)供应商)。

对于与 C++ 互操作的其他语言,选项不太直接。通常,共同点是 C - 其他语言提供与 C 互操作的工具,就像 C++ 一样,因此使用一些 C 接口作为两者之间的中介。例如,在 C++ 中实例化对象的代码可以放在extern "C" 函数中。然后可以使用 C++ 编译器编译该代码,生成的函数具有允许从 C 代码调用它的接口。如果其他语言(或编译器)支持与 C 互操作(即符合正确接口以调用 C 函数的要求),则可以从其他语言调用该 C 函数。

【讨论】:

  • “从技术上讲,gnu C 编译器输出的机器代码可能与其他供应商的 C 编译器输出的代码互操作”GNU C(以及其他所有 C 编译器)会如果没有与本地供应商提供的编译器 100% 二进制兼容性,那么在市场上生存是一个非常的艰难时期。因此,如果您的平台有两个 C 编译器,它们都不低于 1.0 版,那么它们很有可能是二进制兼容的。可能有例外,但我最近没有听说过。
  • @n.m - 比这更复杂。 gcc 包含它自己的 C++ ABI,这与“本地供应商提供的编译器”支持的 ABI 不同。在 gcc 3.4.0(来自内存)之前,不同版本的 gcc ABI 彼此不兼容,这使得很难说它们都与本机支持的 ​​ABI 兼容。在以后的 gcc 版本中,ABI 是向前兼容的(即用旧版本构建的库可以与新版本链接,但不能反向链接)。
  • 我只是在谈论 C 而不是 C++。
【解决方案3】:

至于“extern C”,这不是 C++ 代码。

标记为extern "C" 的C++ 代码是可从C 调用的C++ 代码,因此可从其他非C++ 代码调用。 C是一种语言间接口的通用语言。如果你会说 C,你就可以和任何会说 C 的人交谈,这几乎是编程语言世界中的每个人。 C ABI 相当简单且易于实施。委婉地说,C++ ABI 绝不是(而且它们是 C ABI 的严格超集,因此无论如何您都必须实现它们)。

坚持使用 C 兼容接口。您不是世界上第一个需要从非 C++ 代码创建 C++ 对象的人。每个人都通过extern "C" 代码进行操作。

它调用的 C++ 代码必须按原样使用,而不是添加诸如“extern C”之类的东西。

您无需向现有代码添加任何内容以与其交互。您编写新的 C++ 代码,使其调用旧的 C++ 代码,并标记新代码extern C。没有以任何方式触及旧代码。

【讨论】:

  • 假设您有一个解释器想要调用动态库(如 Linux .so 文件或 Windows .dll 文件)中的 C++ 代码。该解释器具有内置方法以适应不同的 C++ 调用约定,或者为每个此类调用生成 C++ 代码并为每个调用调用 C++ 编译器,是不是更好?
  • @MrE 100% 的时间,你可以实现的东西比你不能实现的东西要好 100%。你知道有哪位口译员实际上能够按照你的建议去做吗?
  • 所有完成的事情都是第一次完成。我只是想减少让它工作的痛苦。能够适应不同的 C++ 调用约定很有用,对我来说似乎很有价值。但我必须从适应至少一种这样的调用约定开始。这就是为什么我要询问有关该公约的问题。
  • 我了解您想成为第一个并在其他人之前做到这一点。超越 Python 并获得很多名声,也许还有一些钱。但是然后问其他人如何做你想做的事是没有效率的。根据定义,他们不知道。
  • 我不是在问如何适应。我问的是“this”指针和调用中任何其他隐藏指针的约定,对于运行 Linux 或 Windows 的 Intel CPU 上的 G++ 约定。
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-11
  • 2021-07-21
相关资源
最近更新 更多