C:结构、联合和枚举的通用术语?
在C语言标准或文献中,是否有结构、联合和枚举类型的通用术语 更新:在处理以下宏时,出现了此问题:C:结构、联合和枚举的通用术语?,c,language-lawyer,C,Language Lawyer,在C语言标准或文献中,是否有结构、联合和枚举类型的通用术语 更新:在处理以下宏时,出现了此问题: /* GCC */ #if defined(__GNUC__) # define TYPEDEF_PACKED_BEGIN(type, tag) \ typedef type __attribute__((packed, aligned(1))) tag # define TYPEDEF_PACKED_END /* Green Hills */ #elif
/* GCC */
#if defined(__GNUC__)
# define TYPEDEF_PACKED_BEGIN(type, tag) \
typedef type __attribute__((packed, aligned(1))) tag
# define TYPEDEF_PACKED_END
/* Green Hills */
#elif defined(__ghs__)
# define TYPEDEF_PACKED_BEGIN(type, tag) \
#pragma pack(1) \
typedef type tag
# define TYPEDEF_PACKED_END \
#pragma pack()
#endif
我看到有一个术语是“标记类型”。其基本原理是,这三个类型类别由标记名称空间中的关键字和标记标识。C标准在几个地方提到了这些标签,尤其是在: 6.2.3标识符的名称空间 […]因此,不同类别的文件都有单独的名称空间 标识符,如下所示:
- 结构、联合和枚举的标记(通过跟随任何关键字struct、union或enum消除歧义)李>
就您的实际用例而言,我同意StoryTeller的回答。这个答案解释了标准中没有这样的定义 不,不是正式的。中讨论了类型。它为某些类型组提供了标签,但没有一个完全包含联合、结构和枚举
C型系统是复杂的,充满了各种各样的术语组 在形式上,没有包含这3种类型的类型类别。就形式类型系统(6.2.5)而言,它们几乎没有共同之处
- 枚举类型被分类为基本类型之一
和struct
是派生类型。这意味着您可以拥有包含其他对象的union
或结构
联合
是聚合类型(与数组一样),但struct
是它自己的类型。以及作为标量类型的union
——它不包含其他对象的实例enum
但是,这三种不同类型有一些共同点: 它们具有使用相同C名称空间的标记(如@StoryTeller在回答中所述): 6.2.3标识符的名称空间
/--/
因此,不同类别的标识符有单独的名称空间,如下所示:
/--/
-结构、联合和枚举的标记(通过遵循任何关键字
struct
、union
或enum
消除歧义)
对于兼容类型,它们共享相同的规则,6.2.7:
此外,如果在单独的翻译单元中声明的两个结构、联合或枚举类型的标记和成员满足以下要求,则它们是兼容的:
因此,虽然它们不是相同的类型,但它们共享相同的标记系统和用于标记的相同名称空间。您的特定编译器利用了这一点,允许它们共享相同的宏进行打包(清除填充)。这对于可以有填充字节的
struct
和union
来说是有意义的,但对于enum
,填充的概念没有任何意义。为什么需要它?而struct
和union
在某种程度上是相似的,enum
不是。也许您正在寻找标量类型和非标量类型?@gsamaras我正在定义一个应该可以使用的宏???(又名结构、联合或枚举)。@gsamaras:确实如此-这不是一个完美的匹配。从未听说过,谢谢!然而,它很少被使用(如果有),如果我在文档或宏的注释中读到它,我会被暗示或迷惑吗?没有人知道这就像在你的评论中使用UB一样O@gsamaras-好吧,看情况而定。标签是一个规范性术语。但我不能判断是否有人应该熟悉它。所以IDK也没听说过“标签类型”。它们是3种不同的类型,但它们共享相同的兼容类型规则,这取决于标记,如C17 6.2.7所述。@Lundin-我的(不完美)回忆来自在线论坛。不太经常(因为,一个人需要多久把这三个聚在一起,真的吗?)。它不符合“正式术语”的模式(因为没有正式术语),但它不是我自己发明的(我没有那么聪明)。在GCC中,“packed
这个属性,附加到enum
,struct
或union
类型定义,指定使用最小所需内存来表示类型。”@是的。但是打包枚举没有任何意义。它们只是美化的整数。但是,我同意“在行上指定-fshort enum
标志等同于在所有enum
定义上指定packed
属性。”
TYPEDEF_PACKED_BEGIN(struct, my_struct_tag) {
int a;
int b;
} my_struct_type;
TYPEDEF_PACKED_END
TYPEDEF_PACKED_BEGIN(enum, my_enum_tag) {
E_FOO,
E_BAR
} my_enum_type;
TYPEDEF_PACKED_END