C ++“替换”为具有灵活数组成员的结构

lem*_*erg 5 c c++ arrays flexible-array-member

考虑下面的C99结构,以灵活的数组成员结尾:

struct hdr
{
  size_t len;   
  size_t free;  
  char buf[];
};
Run Code Online (Sandbox Code Playgroud)

len例如,使用这样的内联函数(放入头文件中)进行访问,并将其buf作为参数:

static inline size_t slen(const char *s)
{
  struct hdr *h = (struct hdr*)(s - (int)offsetof(struct hdr, buf));
  return h->len;
}
Run Code Online (Sandbox Code Playgroud)

这是库的一部分,将使用C编译器进行编译。但是,我想从C ++访问该库。这实质上意味着相应的头文件(带有适当的extern "C" {...}防护)必须是有效的C ++代码。一种可能的解决方案是slen在源代码主体中定义功能,而完全避免使用内联代码,但这不是最佳选择。

我的想法是定义一个有效的虚拟C ++结构,并且可以通过某种方式将其映射到hdr,例如

struct cpp_hdr
{
  size_t len;
  size_t free;
  char buf[1];
}
Run Code Online (Sandbox Code Playgroud)

请注意,我只希望得到正确的(负)的偏移值lenfree; 没有访问buf的意图。

现在我的问题是:是否有任何保证

static inline size_t slen(const char *s)
{
  struct cpp_hdr *h = (struct cpp_hdr*)(s - (int)offsetof(struct cpp_hdr, buf));
  return h->len;
}
Run Code Online (Sandbox Code Playgroud)

可以,得到相同的结果?

Che*_*Alf 3

在形式上没有任何保证,因为 C++ 不支持灵活数组:没有这样的东西,没有这样的语法。

实际上,编译器不会无缘无故地做一些事情。因此不会随意引入任何填充。然而,为了充分说明这一点,我将使用数组大小​​(例如 666)而不是 1,这在更一般的情况下效果更好(例如,1 的小数组char可能会移动到其他结构中的某些填充区域)。好处是,巧妙的分配代码看起来不再简单。所以这必须正确完成。

综上所述,它听起来确实像 16 位 Windows BSTR,只是 a 的BSTR长度和字符串数据之间没有差距。考虑一下这个库是否只是某人无缘无故的重新发明轮子。如果是这样,我建议使用原装轮子。