0

次のような列挙型の値をどのように設定/設定解除しますか。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

コードは次のとおりです。

#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;
}
4

1 に答える 1

6

あなたの列挙型には負の整数定数が含まれていないので、GCCはunsignedあなたの列挙型にint型を与えていると思います。今のような表現

o &= ~FOUR

と同等です

o = o & ~FOUR

RHSでは、ounsignedintおよびsignedintで~FOURあり、型変換ルールにより、signedintはunsignedintに変換されます。また~FOUR、負の数であるため、負の数が符号なし型に暗黙的に変換されるという警告が表示されます。

ロジックに確信がある場合は、警告について心配する必要はありません。またはenum、負の数に等しいダミーを使用して列挙型を符号付きに変換できます。

何かのようなもの

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

また、コードには実行時のバッファオーバーフローの問題があります。関数byte_to_binaryでは9ビットをチェックしていますが、バッファも9バイトです。これは10バイトである必要があり、1つは終了ヌル用です。それを作りstatic char b[10];、すべてがうまくいく

于 2012-04-23T08:59:25.860 に答える