如何从位域转换为指针?

发布于 2024-10-09 20:52:20 字数 602 浏览 9 评论 0原文

我编写了以下代码来生成

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

或 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");

如何让警告消失?无论我尝试什么投射,似乎总是会出现警告。

谢谢, 陈兹

I've written the following bit of code that is producing a

warning: initialization makes pointer from integer without a cast

OR A

warning: cast to pointer from integer of different size

from 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");

How do I get the warning to go away? No matter what I've tried casting, a warning seems to always appears.

Thanks,
Chenz

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

木槿暧夏七纪年 2024-10-16 20:52:20

嗯,为什么你坚持使用指针作为布尔值?这个替代方案怎么样?

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

const struct named_bool bools[] = {{ "ItemA", 1 }, { "ItemB", 1 }, { 0, 0 }};

Hmm, why do you insist on using pointers as booleans? How about this alternative?

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

const struct named_bool bools[] = {{ "ItemA", 1 }, { "ItemB", 1 }, { 0, 0 }};
电影里的梦 2024-10-16 20:52:20
const void * bools[] = { "ItemA", mine->a, "ItemB", mine->b, 0, 0 }; 

此代码片段有几个问题:

  1. mine 未声明为指针类型(至少在您发布的代码中没有),因此您不应使用 ->< /code> 组件选择运算符;
  2. 如果您将其更改为使用 . 选择运算符,您将尝试将布尔值作为指针存储在 a 或 b 中,这不是您想要的;
  3. 但这并不重要,因为您无法获取位字段的地址(第 6.5.3.2 节,第 1 段)。

如果您尝试将布尔值与另一个对象关联,那么最好声明一个类型

struct checkedObject {void *objPtr; int check};

并初始化一个数组,因为

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

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

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

There are several problems with this snippet:

  1. mine isn't declared as a pointer type (at least not in the code you posted), so you shouldn't be using the -> component selection operator;
  2. If you change that to use the . selection operator, you'd be attempting to store the boolean value in a or b as a pointer, which isn't what you want;
  3. But that doesn't matter, since you cannot take the address of a bit-field (§ 6.5.3.2, paragraph 1).

If you're trying to associate a boolean value with another object, you'd be better off declaring a type like

struct checkedObject {void *objPtr; int check};

and initialize an array as

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

Bit-fields have their uses, but this isn't one of them. You're really not saving any space in this case, since at least one complete addressable unit of storage (byte, word, whatever) needs to be allocated to hold the two bitfields.

情场扛把子 2024-10-16 20:52:20

两个问题:

  1. 不确定为什么要尝试将 unsigned int a:1 转换为 void*。如果您尝试引用它,语法将是 &mine->a 而不是 mine->a,但是...

  2. 您可以不创建一个指向 C 中的位的指针(至少据我所知)。如果您尝试创建指向位的指针,您可能需要考虑以下选项之一:

    • 创建一个指向位域结构的指针(即struct my_t *),并(如有必要)使用单独的数字来指示要使用的位。示例:

      struct bit_ref {
          结构my_t *位;
          无符号整数a_or_b; // 0 表示位 ->a,1 表示位 ->b
      }
      
    • 不要使用位字段。对每个标志使用 char,因为它是您可以创建指向的指针的最小数据类型。

    • 确实使用位字段,但通过布尔运算手动实现它。示例:

      typedef unsigned int my_t;
      
      
      #define MY_T_A (1u << 0)
      #define MY_T_B (1u << 1)
      
      
      结构位引用{
          结构my_t *位;
          无符号整型移位;
      };
      
      
      int deref(const struct bit_ref bit_ref)
      {
          return !!(bit_ref.bits & (1 << bit_ref.shift));
      }
      

Two problems:

  1. Not sure why you are trying to convert unsigned int a:1 to a void*. If you are trying to reference it, the syntax would be &mine->a rather than mine->a, but...

  2. You can't create a pointer to a bit in C (at least as far as I know). If you're trying to create a pointer to a bit, you may want to consider one the following options:

    • Create a pointer to the bitfield structure (i.e. struct my_t *), and (if necessary) use a separate number to indicate which bit to use. Example:

      struct bit_ref {
          struct my_t  *bits;
          unsigned int  a_or_b; // 0 for bits->a, 1 for bits->b
      }
      
    • Don't use a bit field. Use char for each flag, as it is the smallest data type that you can create a pointer to.

    • Do use a bit field, but implement it manually with boolean operations. Example:

      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));
      }
      
话少情深 2024-10-16 20:52:20

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

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

这使用 NULL 指针表示 false,并使用一个非空指针(在本例中为 &bools,但指向任何正确存储持续时间的对象就可以了)为 true。然后,您还可以在测试中删除对 unsigned int 的强制转换,以便它只是:(

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

空指针始终计算为 false,非空指针始终计算为 true)。

但是,我确实同意您最好创建一个结构数组。

There's a few ways you could get rid of the warning, but still use a pointer value as a boolean. For example, you could do this:

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

This uses a NULL pointer for false, and a non-null pointer (in this case, &bools, but a pointer to any object of the right storage duration would be fine) for true. You would also then remove the cast to unsigned int in the test, so that it is just:

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

(A null pointer always evaluates as false, and a non-null pointer as true).

However, I do agree that you are better off creating an array of structs instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文