小编Ano*_*Guy的帖子

C问题:无符号整数和按位运算中的填充位(C89)

我有很多代码对无符号整数执行按位运算.我编写了我的代码,假设这些操作是在固定宽度的整数上,没有任何填充位.例如,32位无符号整数的数组,其中所有32位可用于每个整数.

我希望让我的代码更具可移植性,并且我专注于确保我符合C89(在这种情况下).我遇到的一个问题是填充整数.拿这个极端的例子,取自GMP手册:

然而,在Cray矢量系统上,可以注意到short和int总是以8个字节存储(并且sizeof指示),但仅使用32或46位.指甲功能可以通过传递例如8*sizeof(int)-INT_BIT来解决这个问题.

我也在其他地方读过这种类型的填充.我昨晚实际上在SO上读了一篇文章(请原谅我,我没有链接,我将引用类似记忆的内容),如果你有一个带有60个可用位的双,另外4个可以用于填充和那些填充位可以用于某些内部目的,因此它们不能被修改.


因此,假设我的代码是在一个平台上编译的,其中unsigned int类型的大小为4个字节,每个字节为8位,但最重要的2位是填充位.在这种情况下UINT_MAX会是0x3FFFFFFF(1073741823)吗?

#include <stdio.h>
#include <stdlib.h>

/* padding bits represented by underscores */
int main( int argc, char **argv )
{
    unsigned int a = 0x2AAAAAAA; /* __101010101010101010101010101010 */
    unsigned int b = 0x15555555; /* __010101010101010101010101010101 */
    unsigned int c = a ^ b; /* ?? __111111111111111111111111111111 */
    unsigned int d = c << 5; /* ??  __111111111111111111111111100000 */
    unsigned int e = d >> 5; /* ?? __000001111111111111111111111111 */

    printf( "a: …
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation padding bitwise-operators

17
推荐指数
1
解决办法
5103
查看次数

C问题:off_t(和其他有符号整数类型)的最小值和最大值

我偶尔会遇到一个整数类型(例如POSIX有符号整数类型off_t),其中有一个宏的最小值和最大值是有帮助的,但我不知道如何制作一个真正可移植的宏.


对于无符号整数类型,我一直认为这很简单.0最小和~0最大.我已经阅读了几个不同的SO线程,建议使用-1而不是~0为了便携性.这里有一个有争议的有趣线程:
c ++ - 使用-1将所有位设置为true是否安全?- 堆栈溢出

然而,即使在阅读了这个问题后,我仍然感到困惑.另外,我正在寻找兼容C89和C99的东西,所以我不知道是否适用相同的方法.说我有一种类型uint_whatever_t.难道我不能先转为0然后按位补码?这样可以吗?:

#define UINT_WHATEVER_T_MAX ( ~ (uint_whatever_t) 0 )
Run Code Online (Sandbox Code Playgroud)


有符号整数类型看起来像是一个更难以破解的坚果.我已经看到了几种不同的可能解决方案,但只有一种似乎是可移植的.无论是那个还是不正确的.我在谷歌搜索OFF_T_MAX和OFF_T_MIN时找到了它.感谢Christian Biere:

#define MAX_INT_VAL_STEP(t) \
    ((t) 1 << (CHAR_BIT * sizeof(t) - 1 - ((t) -1 < 1))) 

#define MAX_INT_VAL(t) \
    ((MAX_INT_VAL_STEP(t) - 1) + MAX_INT_VAL_STEP(t))

#define MIN_INT_VAL(t) \
    ((t) -MAX_INT_VAL(t) - 1)

[...]
#define OFF_T_MAX MAX_INT_VAL(off_t) 
Run Code Online (Sandbox Code Playgroud)


我找不到关于C89中不同允许类型的有符号整数表示的任何内容,但C99在§J.3.5中有关于整数可移植性问题的注释:

是否使用符号和幅度,二进制补码或一对补码表示有符号整数类型,以及非常值是陷阱表示还是普通值(6.2.6.2).

这似乎意味着只能使用那三个列出的签名数字表示.暗示是否正确,并且上面的宏是否与所有三种表示兼容?


其他想法:如果有填充位
,似乎类似函数的宏MAX_INT_VAL_STEP()会给出不正确的结果.我想知道是否有任何办法解决这个问题.

通过维基百科上的带符号数字表示,我发现对于所有三个有符号整数表示,任何有符号整数类型的MAX都将是:
符号位关闭,所有值位开启(全部三个)
并且其MIN将是:
符号位开启,全部值符号打开(符号和幅度)
符号位打开,所有值位关闭(1 …

c binary bit-manipulation bitwise-operators

11
推荐指数
3
解决办法
4763
查看次数

C问题:单个取消引用void**双间接指针

我收到了这条消息:

expected 'void **' but argument is of type 'char **'
Run Code Online (Sandbox Code Playgroud)

当我尝试编译类似于此的东西:

void myfree( void **v )
{
    if( !v || !*v )
        return;

    free( *v );
    *v = NULL;

    return;
}
Run Code Online (Sandbox Code Playgroud)



我在堆栈溢出后阅读这个问题后发现了我认为的解决方案:
在处理双重间接时避免不兼容的指针警告 - Stack Overflow

所以我调整为这样的事情:

#include <stdio.h>
#include <stdlib.h>

void myfree( void *x )
{
    void **v = x;

    if( !v || !*v )
        return;

    free( *v );
    *v = NULL;

    return;
}

int main( int argc, char *argv[] )
{
    char *test;

    if( ( test = …
Run Code Online (Sandbox Code Playgroud)

c type-conversion void void-pointers compiler-warnings

6
推荐指数
1
解决办法
2004
查看次数