【问题标题】:Define C++ functions in C structs在 C 结构中定义 C++ 函数
【发布时间】:2017-08-01 08:46:36
【问题描述】:

看完

  1. possible to define a function inside a C structure? [duplicate]
  2. Define functions in structs

我想知道以下解决方法是否可行,以及它在编译器级别的最深层含义是什么。

// foo.h
typedef struct foo
{
    int i;
#ifdef __cplusplus
    foo(int _i) : i(_i) {};
#endif
} foo;

// bar.c
#include "foo.h"
foo bar;
bar.i = 1;

// bar.cpp
#include "foo.h"
foo bar(2);

在我看来,这是利用“结构多态性”的一个很好的技巧,能够保持 C 遗留代码的可移植性,但我感觉在某种程度上我现在正在处理两个不同的 类型。

【问题讨论】:

  • 您还使用两种不同的语言...您想达到什么目的?
  • 如果您使用 C 编译器进行编译,则结构中没有 C++ 函数。如果你用 C++ 编译器编译,你就没有 C 结构。是的,你有 2 种完全不同的类型。
  • 环境是一个自己的 C++11 库,除其他库外,它还依赖于旧的 C89 库。我的一些 c 文件是这个库的客户端,并且是 C11 编译的;示例结构将在我的库中大部分共享,我想确保它是完全相同相同的类型。
  • 我认为当您使用 C++ 功能将 vtable 引入您的结构时,这可能最终会中断。
  • 没有“变通方法”,C++ 不是 C,所以两个编译器会产生完全不同的输出。如果您询问这两个结构是否在内存中具有相同的 layout,我建议您自己使用打包指令来确保这一点。关于“结构多态性”,我什至不知道这在 C 中应该是什么意思。

标签: c++ c struct


【解决方案1】:

从您的问题中查看struct 定义:

typedef struct foo
{
    int i;
#ifdef __cplusplus
    foo(int _i) : i(_i) {};
#endif
} foo;

当使用针对同一平台的 C 和 C++ 编译器进行编译时,可能会产生相同的内存表示。但是您应该永远不要依赖它。 C++ 编译器看到的类型比 C 编译器看到的类型多一个成员,因此它们是根本不同的类型。因此,将它们视为相同是未定义的行为。如果这按您的预期工作,那是纯属运气,并且可能随时中断。

正如已经评论过的,引入virtual 函数几乎可以保证破坏它,因为C++ 编译器需要将vtable 存储在struct 的某个位置。但即使没有它,它也有许多其他方式可能会破坏,例如因为编译器会添加不同的填充。只是不要这样做。

您可以做的是使用 plain C struct 并在需要时在 C++ 中添加 包装类

【讨论】:

    【解决方案2】:

    两者是不同的类型。编译为 C 会产生与编译为 C++ 不同的类型。同时在同一个程序中使用两者(即将 C 和 C++ 对象链接到一个可执行文件中),结果将是未定义的行为,因为违反了 C++ 中的单一定义规则。

    这不是保持 C 和 C++ 之间可移植性的方法。该行为是未定义的,因此您可能会很幸运并发现它按您的意愿工作。但是,同样,行为是未定义的,所以它可能不起作用。

    【讨论】:

      【解决方案3】:

      如果你想确保与 C 库的兼容性,这不是办法。

      你想定义一个类型 is-a foo 并且可以传递给库函数。所以就这样做,继承:

      class shiny_foo : foo {
        // Member functions and anything that changes the object layout.
      };
      
      extern "C" void c_bar_func(foo *);
      
      void cxx_bar_func(shiny_foo& obj) {
        // do stuff
        c_bar_func(&obj); // obj *is-a* foo as well, remember
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-20
        • 1970-01-01
        • 1970-01-01
        • 2012-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多