1

我编写了以下代码,它产生了

警告:初始化使指针从整数而不进行强制转换

警告:从不同大小的整数转换为指针

来自 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}};

位域有其用途,但这不是其中之一。在这种情况下,您实际上并没有节省任何空间,因为至少需要分配一个完整的可寻址存储单元(字节、字等)来保存两个位域。

于 2011-01-03T22:28:32.873 回答
0

有几种方法可以消除警告,但仍然使用指针值作为布尔值。例如,您可以这样做:

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

这使用一个NULL指针表示假,一个非空指针(在这种情况下&bools,,但指向任何具有正确存储持续时间的对象的指针都可以)为真。然后,您还可以unsigned int在测试中删除强制转换,以便它只是:

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

(空指针总是计算为假,非空指针总是计算为真)。

但是,我同意你最好创建一个数组structs

于 2011-01-03T23:26:23.430 回答
0

两个问题:

  1. 不知道您为什么要尝试转换unsigned int a:1void*. 如果您尝试引用它,则语法将是&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 回答