负整数隐式转换为无符号类型

mal*_*lat 0 c enums gcc bit-fields

如何为以下内容设置/取消设置枚举值.使用gcc,我收到了这个恼人的警告:

test.c:37: warning: negative integer implicitly converted to unsigned type
test.c:39: warning: negative integer implicitly converted to unsigned type
test.c:41: warning: negative integer implicitly converted to unsigned type
test.c:43: warning: negative integer implicitly converted to unsigned type
Run Code Online (Sandbox Code Playgroud)

代码是:

#include <stdio.h>
#include <string.h>

typedef enum {
 ONE = 0x1,
 TWO = 0x2,
 THREE = 0x4,
 FOUR = 0x8,
} options;

static const char *byte_to_binary (int x)
{
  int z;
  static char b[9];
  b[0] = '\0';

  for (z = 256; z > 0; z >>= 1)
    {
    strcat(b, ((x & z) == z) ? "1" : "0");
    }

  return b;
}

int main(int argc, char *argv[])
{
  options o = 0;
  printf( "%s\n", byte_to_binary(o));
  o |= ONE;
  printf( "%s\n", byte_to_binary(o));
  o |= TWO;
  printf( "%s\n", byte_to_binary(o));
  o |= THREE;
  printf( "%s\n", byte_to_binary(o));
  o |= FOUR;
  printf( "%s\n", byte_to_binary(o));
  o &= ~FOUR;
  printf( "%s\n", byte_to_binary(o));
  o &= ~THREE;
  printf( "%s\n", byte_to_binary(o));
  o &= ~TWO;
  printf( "%s\n", byte_to_binary(o));
  o &= ~ONE;
  printf( "%s\n", byte_to_binary(o));

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Pav*_*ath 6

由于你的枚举不包含任何负整数常量,我猜GCC已经unsigned为你的枚举提供了int类型.现在的表达式就像

o &= ~FOUR
Run Code Online (Sandbox Code Playgroud)

相当于

o = o & ~FOUR
Run Code Online (Sandbox Code Playgroud)

在RHS上,o是unsigned int并且~FOUR是signed int并且通过类型转换规则,signed int将被转换为unsigned int.也是~FOUR一个负数,因此您会收到一个警告,将负数隐式转换为无符号类型.

如果您确定自己的逻辑,则无需担心警告,或者您可以通过使用enum等于负数的虚拟对象将您的枚举转换为签名.

就像是

typedef enum {
 DUMMY =-1,
 ONE = 0x1,
 TWO = 0x2,
 THREE = 0x4,
 FOUR = 0x8,
} options;
Run Code Online (Sandbox Code Playgroud)

此外,您的代码有运行时缓冲区溢出问题.在函数中,byte_to_binary您正在检查9位,但您的缓冲区也是9个字节.它必须是10个字节,一个用于终止空值.做它static char b[10];,一切正常