为什么_BIT
中有limits.h
,CHAR_BIT
,LONG_BIT
的{{1}}宏?为什么不定义WORD_BIT
?
是否为其他类型而不是INT_BIT
定义了这些宏?这些int
已弃用(不使用)吗?
我看到这些是由POSIX for limits.h
答案 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
宏。
编辑: