我已将工作环境从ubuntu 12.04升级到14.04。
这导致我的编译器clang
从3.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新版本)显示错误。
答案 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
所需的数据,并在每次需要时在本地创建一个新数据。我不知道在您的情况下,终身问题是否允许这样做。