代码之家  ›  专栏  ›  技术社区  ›  sharptooth

如何在编译时测试常量是否适合类型?

  •  3
  • sharptooth  · 技术社区  · 14 年前

    //assumes typedef unsigned char BYTE;
    int value = ...;
    // Does it fit into BYTE?
    if( 0 <= value && value <= UCHAR_MAX ) {
        BYTE asByte = static_cast<BYTE>( value );
        //proceed with byte
    } else {
        //proceed with greater values
    }
    

    问题是 UCHAR_MAX BYTE 是独立的 typedef 当这个代码被移植时,它们可能会失去同步,代码会中断。所以我想这样做:

    compileTimeAssert( sizeof( BYTE ) == sizeof( UCHAR_MAX ) );
    

    但是VC++9在编译时会产生“负下标”错误- sizeof( UCHAR_MAX ) 正好是4,不是1。

    如何实现所需的编译时检查?

    5 回复  |  直到 14 年前
        1
  •  2
  •   Community Tales Farias    7 年前

    ( (1 << (sizeof(BYTE)*CHAR_BIT)) - 1 ) == UCHAR_MAX .

    (我假设您没有询问如何执行静态断言—有几种方法,请参阅 here

        2
  •  5
  •   usta    14 年前

    将“value”与std::numeric\u limits<BYTE>::max()进行比较,而不是UCHAR\u max

        3
  •  1
  •   Pontus Gagge    14 年前
        4
  •  1
  •   Chubsdad    14 年前

    但是VC++9会产生“负的” -sizeof(UCHAR_MAX)恰好是4,而不是1。

    在这篇文章中,我不是在回答问题的解决办法,而是试图找到问题的根源。

    #define MAX 255;

    我的理解是 sizeof(MAX) a.k.a (sizeof(255)) 根据标准2.3.1/2中的给定规则,总是给定平台上整数文本的大小。仅仅因为它是UCHAR_MAX,并且持有a的最大值 char 并不意味着这样一个名字的大小将是 烧焦

    整数文本的类型取决于 是十进制的,没有后缀,它有 第一种 值可以表示为:int,long int;如果值不能为 行为未定义。如果是八进制 或者十六进制,没有后缀 有这些类型中的第一个 它的值可以表示为:int, 如果它的后缀是u或u 类型是这些类型中的第一个 unsigned int,unsigned long int。如果 后缀为l或l,其类型为 值可以表示为:long int, 无符号长整型。如果有后缀 它的类型是unsigned long int。

    所以我们的期望是 1 需要重新检查这似乎是根本原因。 sizeof(MAX) int 宽如一个 烧焦 . 我不知道到底有多少这样的系统。

        5
  •  1
  •   adf88    14 年前

    UCHAR_MAX unsigned char . 的大小 总是1字节。如果你想检查 BYTE 0 .. UCHAR_最大值 -(UCHAR_MAX/2+1) UCHAR_MAX/2 然后简单地检查一下 sizeof(BYTE) == 1

    如果要检查某个int值是否适合字节,请执行以下操作:

    if (!(value & ~(BYTE)-1)) ...