为什么不与位域变量正常的允许? [英] Why aren't bitfields allowed with normal variables?

查看:168
本文介绍了为什么不与位域变量正常的允许?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么位域与工会/结构而不是像普通变量工作 INT 。< BR>
这工作:

 结构foo的{
    INT条:10;
};

但这种失败:

  INT条:10; //预期;在声明的末尾

为什么这个功能仅在工会组织/结构,而不是与变量可用?是不是它的技术一样呢?


编辑:

如果将它允许你能与例如3个字节的变量,而不每次使用的结构/联合成员。这是我如何与一个结构到它:

 结构int24_t {
    INT X:24 __attribute __((打包));
};结构int24_t VAR; //的sizeof(VAR)现在3
//访问的价值会更容易些:
var.x = 123;


解决方案

这是一个主观的问题,为什么说规范呢?但我给它我的投篮。

在一个函数的变量通常具有自动存储,相对于其他的持续时间中的一个(静态持续时间,螺纹持续时间,和分配持续时间)。

在一个结构,你明确地定义一些对象的内存布局。但是,在一个函数,编译器自动以某种方式不详为变量分配存储空间。这里有一个问题:有多少字节没有 X 在堆栈上占用

  //的sizeof(无符号)== 4
无符号X;

有可能需要长达4个字节,或它可能需要长达8,或12,或0,或者它可以得到安置在三个不同的寄存器,同时,或在堆栈和一个寄存器,或者它可以得到四个位置在堆栈中。

问题的关键是,编译器为你做的分配。既然你没有做堆栈的布局,你不应该指定位宽。

扩展讨论:位字段实际上是一个有点特殊。规范指出相邻位域得到包装到同一存储单元。位字段是不实际的对象。


  1. 您不能的sizeof() A位字段。


  2. 您不能的malloc() A位字段。


  3. 您不能&放大器; addressof A位域


所有这些事情,你可以在C对象做,但不能与位域。位域只是结构和无处做了一个特别的东西。

关于 int24_t (更新):它工作在某些架构,而不是其他。它甚至不是的的便携性。

  typedef结构{
    INT X:24 __attribute __((打包));
} int24_t;

在Linux的ELF / 64,Mac OS X / 86,Mac OS X / 64,的sizeof(int24_t)== 3 。但在OS X / PowerPC上,的sizeof(int24_t)== 4

请注意在code GCC生成装载 int24_t 基本上是相同的:

  INT结果=(((字符*)PTR)[0]&LT;&LT; 16)|
             (((无符号字符*)PTR)[1];&LT; 8)|
             ((无符号字符*)PTR)[2];

这是在x64 9的说明,只是加载一个值。

I wonder why bitfields work with unions/structs but not with a normal variable like int or short.
This works:

struct foo {
    int bar : 10;
};

But this fails:

int bar : 10; // "Expected ';' at end of declaration"

Why is this feature only available in unions/structs and not with variables? Isn't it technical the same?


Edit:

If it would be allowed you could make a variable with 3 bytes for instance without using the struct/union member each time. This is how I would to it with a struct:

struct int24_t {
    int x : 24 __attribute__((packed));
};

struct int24_t var; // sizeof(var) is now 3
// access the value would be easier:
var.x = 123;

解决方案

This is a subjective question, "Why does the spec say this?" But I'll give it my shot.

Variables in a function normally have "automatic" storage, as opposed to one of the other durations (static duration, thread duration, and allocated duration).

In a struct, you are explicitly defining the memory layout of some object. But in a function, the compiler automatically allocates storage in some unspecified manner to your variables. Here's a question: how many bytes does x take up on the stack?

// sizeof(unsigned) == 4
unsigned x;

It could take up 4 bytes, or it could take up 8, or 12, or 0, or it could get placed in three different registers at the same time, or the stack and a register, or it could get four places on the stack.

The point is that the compiler is doing the allocation for you. Since you are not doing the layout of the stack, you should not specify the bit widths.

Extended discussion: Bitfields are actually a bit special. The spec states that adjacent bitfields get packed into the same storage unit. Bitfields are not actually objects.

  1. You cannot sizeof() a bit field.

  2. You cannot malloc() a bit field.

  3. You cannot &addressof a bit field.

All of these things you can do with objects in C, but not with bitfields. Bitfields are a special thing made just for structures and nowhere else.

About int24_t (updated): It works on some architectures, but not others. It is not even slightly portable.

typedef struct {
    int x : 24 __attribute__((packed));
} int24_t;

On Linux ELF/x64, OS X/x86, OS X/x64, sizeof(int24_t) == 3. But on OS X/PowerPC, sizeof(int24_t) == 4.

Note the code GCC generates for loading int24_t is basically equivalent to this:

int result = (((char *) ptr)[0] << 16) |
             (((unsigned char *) ptr)[1] << 8) |
             ((unsigned char *)ptr)[2];

It's 9 instructions on x64, just to load a single value.

这篇关于为什么不与位域变量正常的允许?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆