我想声明一个使用冒号指定大小的位域(我不记得语法是什么)。我想这样写:
void myFunction()
{
unsigned int thing : 12;
...
}
但是GCC表示这是语法错误(它认为我正在尝试编写嵌套函数)。我这样做没有问题:
struct thingStruct
{
unsigned int thing : 4;
};
然后将一个这样的结构放在堆栈上
void myFunction()
{
struct thingStruct thing;
...
}
这使我相信它是由语法而不是语义问题阻止的。
那么第一个示例为什么不起作用?我想念什么?
最佳答案
正如其他人所说,位域必须在struct
(或union
内)中声明,但这并不是真的有用。为什么?这有两个原因。
主要是为了简化编译器编写器的工作。位域往往需要更多的机器指令来从字节中提取位。只有字段可以是位字段,不能是变量或其他对象,因此,如果不涉及.
或->
运算符,则编译器编写程序不必担心它们。
但是,您说过,有时语言设计人员会使编译器编写者的工作更加艰苦,以便使程序员的生活更轻松。嗯,程序员对struct
以外的位域的需求并不多。原因是当程序员要在单个数据结构中填充几个小整数时,程序员几乎只对位域感到困扰。否则,他们将使用普通整数类型。
其他语言具有整数范围类型,例如,您可以指定一个介于17到42之间的变量。在C中对此没有太多要求,因为C永远不需要实现检查溢出。因此,C程序员只需选择一种能够表示所需范围的类型即可。无论如何,检查边界是他们的工作。
C89(即,随处可见的C语言版本)提供了至少n位类型的有限选择。有8位的unsigned char
,16位的unsigned short
和32位的unsigned long
(加上带符号的变体)。 C99提供了更广泛的类型,称为uint_least8_t
,uint_least16_t
,uint_least32_t
和uint_least64_t
。保证这些类型是最小的类型,至少具有多个值位。一个实现可以为其他位数提供类型,例如uint_least12_t
,但是大多数不提供。这些类型在<stdint.h>
中定义,即使标准不要求,也可以在许多C89实现中使用这些类型。