为什么没有INT_BIT?

时间:2018-09-18 22:18:21

标签: c posix

为什么_BIT中有limits.hCHAR_BITLONG_BIT的{​​{1}}宏?为什么不定义WORD_BIT

是否为其他类型而不是INT_BIT定义了这些宏?这些int已弃用(不使用)吗?

我看到这些是由POSIX for limits.h

定义的

2 个答案:

答案 0 :(得分:4)

从您链接到的文档来看,WORD_BIT就是您想要的INT_BIT

  

{WORD_BIT}类型为{strong> int的对象中的位数。

请注意,CX表示这是对标准C的扩展。

C99 rationale document告诉我们,委员会认为CHAR_BIT之外的任何事情都没有理由:

  

CHAR_BIT使char对象中的位数可用。 C89 委员会在为其他数据类型添加此类宏方面见效甚微。

可能是因为CHAR_BIT*sizeof(type)完成了您需要的工作。

答案 1 :(得分:0)

您可以在构建时通过计算相应的无符号最大值中的位数来生成它们。

z=len(z)

在我的平台上,以上内容让我:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int popcnt(unsigned long long X) { int pc=0;for(;(X&1);pc++,X>>=1){;} return pc; }
int main()
{
    if(0>printf("#define CHAR_BIT %d\n", popcnt(UCHAR_MAX))) return EXIT_FAILURE;
    if(0>printf("#define UCHAR_BIT %d\n", popcnt(UCHAR_MAX))) return EXIT_FAILURE;
    if(0>printf("#define SCHAR_BIT %d\n", popcnt(UCHAR_MAX))) return EXIT_FAILURE;
    if(0>printf("#define SHRT_BIT %d\n", popcnt(USHRT_MAX))) return EXIT_FAILURE;
    if(0>printf("#define USHRT_BIT %d\n", popcnt(USHRT_MAX))) return EXIT_FAILURE;
    if(0>printf("#define INT_BIT %d\n", popcnt(UINT_MAX))) return EXIT_FAILURE;
    if(0>printf("#define UINT_BIT %d\n", popcnt(UINT_MAX))) return EXIT_FAILURE;
    if(0>printf("#define LONG_BIT %d\n", popcnt(ULONG_MAX))) return EXIT_FAILURE;
    if(0>printf("#define ULONG_BIT %d\n", popcnt(ULONG_MAX))) return EXIT_FAILURE;
    if(0>printf("#define LLONG_BIT %d\n", popcnt(ULLONG_MAX))) return EXIT_FAILURE;
    if(0>printf("#define ULLONG_BIT %d\n", popcnt(ULLONG_MAX))) return EXIT_FAILURE;
    if(0>fclose(stdout)) return EXIT_FAILURE;
    return EXIT_SUCCESS;
}

(请注意,由于C标准允许使用本机类型中的填充位,因此从技术上讲,不能保证这些#define CHAR_BIT 8 #define UCHAR_BIT 8 #define SCHAR_BIT 8 #define SHRT_BIT 16 #define USHRT_BIT 16 #define INT_BIT 32 #define UINT_BIT 32 #define LONG_BIT 64 #define ULONG_BIT 64 #define LLONG_BIT 64 #define ULLONG_BIT 64 。)

如果在要支持的任何平台上构建之前运行这段代码对您来说很烦,

使用这个小巧的Shell脚本,您可以(对于每个平台一次)生成一个完美的整数常量表达式保留的无UB调用(希望)sizeof(the_type)*CHAR_BIT cpp-macro最多N位整数:

popcnt

宏的256位变体仅为(!)605KB。因此,您实际上并不需要那些#!/bin/sh -eu gen() { Max=$1 local i=0; prev='(X)' #continuous popcount at compile time printf '#define contpopcnt(X) %s\n' "(($prev&1)\\" i=1; while [ $i -le $Max ]; do #look 1 bit ahead the left shift never reaches or exceeds #the width of whatever X's type might be (would be UB) prev="(($prev&2)?((X)>>$i):0)" printf '+(%s&1)\\\n' "$prev" i=$((i+1));done printf ')\n' } gen 256 cat<<EOF //#define CHAR_BIT contpopcnt(UCHAR_MAX) #define UCHAR_BIT contpopcnt(UCHAR_MAX) #define SCHAR_BIT contpopcnt(UCHAR_MAX) #define SHRT_BIT contpopcnt(USHRT_MAX) #define USHRT_BIT contpopcnt(USHRT_MAX) #define INT_BIT contpopcnt(UINT_MAX) #define UINT_BIT contpopcnt(UINT_MAX) #define LONG_BIT contpopcnt(ULONG_MAX) #define ULONG_BIT contpopcnt(ULONG_MAX) #define LLONG_BIT contpopcnt(ULLONG_MAX) #define ULLONG_BIT contpopcnt(ULLONG_MAX) //a little sanity check #include <limits.h> #include <stdint.h> #if CHAR_BIT!=contpopcnt(UCHAR_MAX) #error "oops" #endif EOF 宏。

编辑:

一种更紧凑的方法:https://stackoverflow.com/a/4589384/1084774