错误:C2016 C 要求结构或联合至少有一个成员

Posted

技术标签:

【中文标题】错误:C2016 C 要求结构或联合至少有一个成员【英文标题】:Error:C2016 C requires that a struct or union has at least one member 【发布时间】:2019-01-08 16:48:15 【问题描述】:

我是 c/c++ 的新手,在使用 c++ 中的一些 c 项目标头时遇到了问题。

我有两种解决方案,其中 #one 主要包含 c 文件(也很少有 cpp)和 #two 仅包含 cpp 文件。每个解决方案都被编译并正确运行,没有错误。 两者都在 VisualStudio v.15.9.4 VC++ 2017 上以 windows SDK 10.0.17134.0 为目标。

我确实将一些头文件从 #one 复制粘贴到 #two 并在编译时得到标题中的错误。

typedef struct

    U32 RESERVED;
    SHARED_TYPE *  SHARED;
    struct
    
     ALIEN; <--- HERE
 TxRequest;

Error   C2016   C requires that a struct or union has at least one member 
Error (active)  E0169   expected a declaration

主要搜索关于编译器差异的答案,但 针对相同的 SDK,不是两种解决方案都使用相同的编译器?为什么在一个解决方案中编译时没有错误,而在一个解决方案中编译时出错?

我应该如何修复它具有相同的空结构。因为更改它可能会影响其他部分。

【问题讨论】:

空结构体的作用是什么? C++ 支持空结构,但我真的很想知道有什么用例。 @Jabberwocky:抛出该类型的异常是一种用例。 @NathanOliver 还不知道,它是包含数百个文件的协议栈的一部分 C 和 C++ 是不同的语言。它们共享一个共同的子集,但彼此之间也存在不兼容性。假设您可以选择任意 C++ 代码并将其编译为 C 语言,或者反之亦然,这绝不是安全的。使用的编译器在某种意义上与它无关。 【参考方案1】:

标准 C 不允许空结构,因为错误消息很有帮助地指出。标准 C++ 确实允许使用它们,因为它们可用作模板元值和重载解析等用途。

从错误消息来看,您似乎正在使用 Visual Studio C 编译器编译该标头。

其他编译器更宽松。空 C 结构是长期存在的 GCC 扩展,并且经常使用,如本例所示,作为所谓的"struct hack" 的另一种形式。在其经典形式中,struct hack 包括放置一个长度为 1 的数组(或者,使用 gcc,长度为 0)作为一种可变长度扩展的占位符。在这种情况下,可变长度扩展可能是未指定类型的单个对象,而不是经典的 struct hack,后者是指定类型但未指定长度的对象数组。

所以 GCC(和 Clang)接受 struct 声明为有效 C,除非您请求使用 -pedantic 进行严格验证(即使这样,它也会显示为警告,而不是错误)。

一般来说,union 会是一个更好的解决方案。但这需要了解TxRequest 的各种可能扩展,因此它可能比它的价值更麻烦。

【讨论】:

我仍然没有得到,Visual Studio 如何以及为什么使用两个不同的编译器编译它们?有没有办法强制 VS 用同一个编译器编译这两个解决方案? @amir:我相信一个被编译为 C,另一个被编译为 C++。这不取决于标题。重要的是包含标题的文件中使用的语言。

以上是关于错误:C2016 C 要求结构或联合至少有一个成员的主要内容,如果未能解决你的问题,请参考以下文章

目标 C:在非结构或联合的情况下请求成员 XXX。 (核心数据)

在非结构或联合的事物中请求成员'_file'[关闭]

编译时在非结构或联合中获取成员“indexPath”的错误请求

编译错误:请求非结构或联合中的成员

C++ 成员引用基类型'Vertex *const'不是结构或联合

面试要求