1

私は次のコードを作成しました。

警告:初期化により、キャストなしで整数からポインタが作成されます

またはA

警告:異なるサイズの整数からポインタにキャストします

gcc(GCC)4.1.1 20070105(Red Hat 4.1.1-52)から

struct my_t {
  unsigned int a     : 1;
  unsigned int b    : 1;
};

struct my_t mine = {
  .a = 1,
  .b = 0
};

const void * bools[] = { "ItemA", mine->a, "ItemB", mine->b, 0, 0 };

int i;
for (i = 0; bools[i] != NULL; i += 2)
  fprintf(stderr, "%s = %d\n", bools[i], (unsigned int) bools[i + 1] ? "true" : "false");

警告が消えるにはどうすればよいですか?何をキャストしようとしても、いつも警告が出ているようです。

ありがとう、チェンツ

4

4 に答える 4

2

うーん、なぜあなたはポインタをブール値として使うことを主張するのですか?この代替案はどうですか?

struct named_bool {
    const char* name;
    int         val;
};

const struct named_bool bools[] = {{ "ItemA", 1 }, { "ItemB", 1 }, { 0, 0 }};
于 2011-01-03T22:04:55.297 に答える
1
const void * bools[] = { "ItemA", mine->a, "ItemB", mine->b, 0, 0 }; 

このスニペットにはいくつかの問題があります。

  1. mine(少なくとも投稿したコードでは)ポインター型として宣言されていないため、->コンポーネント選択演算子を使用しないでください。
  2. 選択演算子を使用するようにこれを変更すると.、ブール値をaまたはbにポインターとして格納しようとしますが、これは目的ではありません。
  3. しかし、ビットフィールドのアドレスを取得することはできないため、それは問題ではありません(§6.5.3.2、段落1)。

ブール値を別のオブジェクトに関連付けようとしている場合は、次のような型を宣言することをお勧めします。

struct checkedObject {void *objPtr; int check};

配列を次のように初期化します

struct checkedObject[] = {{"ItemA", 1}, {"ItemB", 0}, {NULL, 0}};

ビットフィールドには用途がありますが、これはその1つではありません。この場合、2つのビットフィールドを保持するために、少なくとも1つの完全なアドレス指定可能なストレージユニット(バイト、ワードなど)を割り当てる必要があるため、実際にはスペースを節約していません。

于 2011-01-03T22:28:32.873 に答える
0

2つの問題:

  1. unsigned int a:1に変換しようとしている理由がわかりませんvoid*。あなたがそれを参照しようとしているなら、構文はで&mine->aはなくmine->a、しかし...

  2. Cのビットへのポインタを作成することはできません(少なくとも私が知る限り)。ビットへのポインタを作成しようとしている場合は、次のいずれかのオプションを検討することをお勧めします。

    • ビットフィールド構造へのポインタを作成し(つまりstruct my_t *)、(必要に応じて)別の番号を使用して使用するビットを示します。例:

      struct bit_ref {
          struct my_t  *bits;
          unsigned int  a_or_b; // 0 for bits->a, 1 for bits->b
      }
      
    • ビットフィールドは使用しないでください。charポインタを作成できる最小のデータ型であるため、各フラグに使用します。

    • ビットフィールドを使用しますが、ブール演算を使用して手動で実装します。例:

      typedef unsigned int my_t;
      
      
      #define MY_T_A (1u << 0)
      #define MY_T_B (1u << 1)
      
      
      struct bit_ref {
          struct my_t  *bits;
          unsigned int  shift;
      };
      
      
      int deref(const struct bit_ref bit_ref)
      {
          return !!(bit_ref.bits & (1 << bit_ref.shift));
      }
      
于 2011-01-03T22:13:06.473 に答える
0

警告を取り除く方法はいくつかありますが、それでもポインタ値をブール値として使用します。たとえば、次のようにすることができます。

const void * bools[] = { "ItemA", mine->a ? &bools : 0, "ItemB", mine->b ? &bools : 0, 0, 0 };

これは、NULLfalseの場合はポインターを使用し、trueの場合はnull以外のポインター(この場合は&bools、ですが、適切なストレージ期間の任意のオブジェクトへのポインターで問題ありません)を使用します。unsigned int次に、テストでキャストを削除して、次のようにします。

fprintf(stderr, "%s = %d\n", bools[i], bools[i + 1] ? "true" : "false");

(nullポインターは常にfalseと評価され、null以外のポインターはtrueと評価されます)。

ただし、代わりにの配列を作成する方がよいことに同意しますstructs

于 2011-01-03T23:26:23.430 に答える