在C语言中是否有一点类似于sizeof()的语言?

在C语言中是否有一点类似于sizeof()的语言?,c,sizeof,bit-fields,C,Sizeof,Bit Fields,Sizeof()应用于位字段时不起作用: # cat p.c #include<stdio.h> int main( int argc, char **argv ) { struct { unsigned int bitfield : 3; } s; fprintf( stdout, "size=%d\n", sizeof(s.bitfield) ); } # gcc p.c -o p p.c: In function ‘main’: p.c:

Sizeof()应用于位字段时不起作用:

# cat p.c
  #include<stdio.h>
  int main( int argc, char **argv )
  {
    struct { unsigned int bitfield : 3; } s;
    fprintf( stdout, "size=%d\n", sizeof(s.bitfield) );
  }
# gcc p.c -o p
  p.c: In function ‘main’:
  p.c:5: error: ‘sizeof’ applied to a bit-field
#cat p.c
#包括
int main(int argc,字符**argv)
{
结构{无符号整数位域:3;}s;
fprintf(stdout,“大小=%d\n”,sizeof(s.bitfield));
}
#gcc p.c-o.p
p、 c:在函数“main”中:
p、 c:5:错误:“sizeof”应用于位字段
…很明显,因为它不能返回浮点部分大小或其他。然而,它提出了一个有趣的问题在C语言中,是否有一个等价物可以告诉您变量/类型中的位数?理想情况下,除了位字段之外,它还适用于常规类型,如char和int

更新:

如果位字段没有与sizeof()等效的语言,那么在运行时计算它的最有效方法是什么!假设您有依赖于此的循环,并且如果您更改位字段的大小,您不希望它们中断-并且没有公平的欺骗和将位字段大小和循环长度设置为宏。;-)


您无法确定C中位字段的大小。但是,您可以使用limits.h中的
CHAR\u bit
的值来确定其他类型位的大小。以位为单位的大小只是
CHAR\u BIT
*sizeof(type)

不要假设一个C字节是八位字节,它至少是8位。有些实际机器具有16位甚至32位字节

关于您的编辑: 我会说一个位域
inta:n的大小为n位。当放入结构时,额外的填充位属于结构,而不属于位字段


我的建议是:不要使用位字段,而是使用(数组)
无符号字符
,并使用位掩码。这样,许多行为(溢出、无填充)都得到了很好的定义。

使用sizeof()不可能找到位字段的大小。参见C99:

  • 6.5.3.4 sizeof()显然不支持sizeof运算符
    ,位字段
  • 6.7.2.1结构和联合说明符
    在此澄清,位字段不是自立成员
否则,您可以尝试分配给位字段成员-1u(设置了所有位的值),然后查找最高有效位的索引。例如(未经测试):


更多信息。

+1酷,不知道CHAR\u位。如果您需要在运行时计算位字段大小呢?这是不可能的(人们避免使用位字段的原因之一)。编译器可以实现它作为它的扩展,但我从来没有听说过。@Dummy00001:对不起,你错了。C99标准将字符位的下限设为8。在附录J 3.4中,它明确表示为实现定义的行为“字节中的位数”。@Dummy00001:我同意机器字节!=C字节。但字符并不总是8位。5.2.4.2.1:
“其实现定义值的大小(绝对值)应等于*或大于*所示值,并带有相同符号。”
,然后显示:
“-非位字段(字节)字符的最小对象的位数8”
。和6.2.6.1:
“存储在任何其他对象类型的非位域对象中的值由n×CHAR\u位组成,其中n是该类型对象的大小,以字节为单位。”
这个愚蠢的
CHAR\u位
参数何时会消失?在除DSP和30多年历史的传统大型机以外的任何设备上,
CHAR\u位
为8。POSIX需要
CHAR\u BIT==8
,Windows与x86绑定,其中
CHAR\u BIT==8
,整个互联网和联网机器之间的互操作性都建立在八位字节上。除非您有一个非常不寻常的目标(在这种情况下,您的代码可能无论如何都不会是可移植的),否则根本没有必要考虑
CHAR\u位的可能性=8
+1这是一个更接近最佳长度查找器的搜索。什么是
ffs()
?@eruciform:ffs=查找第一组。一种函数(通常直接映射到CPU指令),用于查找int中设置的第一位。位从1开始编号。如果input int为0,那么return太0了。很好!这绝对是我从未见过的函数。在这里,我想这些年来我基本上访问了C的蛛网密布的角落!没有(可移植的)方法在编译时计算
ffs
,因此这通常是低效的。但是,您的循环可能不依赖于位的计数,而只是在位上循环,在这种情况下,您可以使用-1初始化位字段,并执行类似于(counter.bf=-1;counter.bf;counter.bf>>=1)
的操作。(提示:这仅在您的位字段是无符号的情况下才有效)请注意,ffs是一个POSIX函数,不适用于所有平台,也不适用于大于int的数据类型。当然,您可以滚动自己的实现,但这会有点慢。非常确定结构的布局是在编译时确定的。因此,虽然原则上可以在运行时检查它(尽管C没有提供这样做的方法,如果我正确阅读下面的答案的话),但一旦编译发生,它将是不变的(对于特定平台上的特定编译器;当然,它可能会因编译器和平台的不同而不同,基于字边界优化等)。
s.bitfield = -1u;
num_bits = ffs(s.bitfield+1)-1;