2016-01-13 71 views
1

我已经将工作环境从Ubuntu 12.04升级到14.04。 这导致我的编译器clang3.0-6ubuntu3升级到3.4-1ubuntu3C++:错误:基类有一个灵活的阵列成员

当我编译我的代码现在我得到一个错误,我没有用得到:

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 */ 
}; 

接下来,我看了一下__flexarrhere但我没有设法弄清楚什么地方出了问题,或者我该如何解决它。 任何帮助将不胜感激。


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

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

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

这不是一个新的鳕鱼,它在我们的回购很长一段时间。我仍然不明白为什么从ubuntu 12.04升级到14.04(还有新版本的clang)显示错误。

回答

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)解决方案我能想到的是,我的头顶上是以外的类,通过动态分配它。将std::unique_ptr<inotify_event>成员存储在您的班级中,并使用std::make_unique<inotify_event>()进行设置。然后把它看作一个普通的指针,但不要担心new/delete

所以需要额外的拨款,但其他解决方案,我能想到的涉及哑类,看起来几乎inotify_event,和一个非常可疑的演员。

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

+0

谢谢。查看我的更新。 –

+0

@AndyThomas我加了一些想法。尽管没有明确的解决方案,这取决于你,因为只有你真的了解你的代码库。 – BoBTFish