c ++:错误:基类有一个灵活的数组成员

时间:2016-01-13 10:40:37

标签: c++ clang

我已将工作环境从ubuntu 12.04升级到14.04。 这导致我的编译器clang3.0-6ubuntu3升级到3.4-1ubuntu3

当我编译我的代码时,我收到的错误是我没有用来获取:

error: base class has a flexible array member

我遵循了代码,发现我使用的是inotify.h

#include <sys/inotify.h>

在这个文件里面有这个结构:

struct inotify_event {
    int     wd;     /* watch descriptor */
    uint32_t        mask;       /* watch mask */
    uint32_t        cookie;     /* cookie to synchronize two events */
    uint32_t        len;        /* length (including nulls) of name */
    char        name __flexarr; /* stub for possible name */
};

接下来,我了解了__flexarr here,但我没有设法理解出了什么问题,或者我该如何修复它。 任何帮助将不胜感激。

更新:作为BobTFish回答的后续内容,这里是在我的代码中使用inotify_event。

我有一个名为inotify_condition_c的班级,其成员类型为inotify_event,我们称之为m_notify_event

我有几个继承自inotify_condition_c的类。 编译错误clang返回指向那些派生类。

这不是我们回购中很长时间的新鳕鱼。我仍然不明白为什么从ubuntu 12.04升级到14.04(以及clang新版本)显示错误。

1 个答案:

答案 0 :(得分:5)

__flexarr是一个C技巧,你在struct的末尾放置一个空数组,然后在struct的实例之后立即放置你想要的数据,所以你可以将额外的数据视为数组的一部分。所以inotify_event

|wd|mask|cookie|len|name|some|extra|data|
                         ^^^^^^^^^^^^^^^ can be accessed with name[0], name[1], etc.

如果有一个类继承自另一个类:

struct Base {
    int a;
};
struct Derived : Base {
    int b;
}

它(通常)会在内存中布局,以便Derived的数据紧跟Base的数据:|a|b|

应该清楚,这两种技术是不相容的。因此,当您尝试使用灵活数组派生类时,clang似乎引入了一个错误,例如inotify_event

代码中的某处,某些内容继承自inotify_event。你不能这样做。

然而,在我们看到该课程之前,我们无法建议如何修复它。如果您能找到该课程,将其编辑到您的问题中,并解释如何使用该课程,我们可能会进一步提供帮助。

修改
我能想到的最不好(即不涉及某种程度的UB)解决方案是将inotify_event存储在你的类之外,通过动态分配它。在您的班级中存储std::unique_ptr<inotify_event>成员,并使用std::make_unique<inotify_event>()进行设置。然后将其视为普通指针,但不要担心new / delete

所以它涉及额外的分配,但我能想到的另一个解决方案涉及一个虚拟类,它看起来像<{1}} 几乎,并且是一个非常可疑的演员。

另一种可能性是存储重建inotify_event所需的数据,并在每次需要时在本地创建一个新数据。我不知道在您的情况下,终身问题是否允许这样做。