我编写了以下代码来生成
警告:初始化使得整数指针不带强制转换
或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");
如何让警告消失?无论我试图投射什么,似乎总会出现警告。
谢谢, Chenz
答案 0 :(得分:2)
struct named_bool {
const char* name;
int val;
};
const struct named_bool bools[] = {{ "ItemA", 1 }, { "ItemB", 1 }, { 0, 0 }};
答案 1 :(得分:1)
const void * bools[] = { "ItemA", mine->a, "ItemB", mine->b, 0, 0 };
此代码段有几个问题:
mine
未声明为指针类型(至少不在您发布的代码中),因此您不应使用->
组件选择运算符;
.
选择运算符,你将试图将布尔值存储在a或b中作为指针,这不是你想要的;
如果您尝试将布尔值与另一个对象相关联,那么最好声明类似
的类型struct checkedObject {void *objPtr; int check};
并将数组初始化为
struct checkedObject[] = {{"ItemA", 1}, {"ItemB", 0}, {NULL, 0}};
比特字段有它们的用途,但这不是其中之一。在这种情况下,你真的没有节省任何空间,因为至少需要分配一个完整的可寻址存储单元(字节,字,等等)来保存两个位域。
答案 2 :(得分:0)
两个问题:
不确定为什么要将unsigned int a:1
转换为void*
。如果您尝试引用它,则语法为&mine->a
而不是mine->a
,但是......
你不能在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));
}
答案 3 :(得分:0)
有几种方法可以摆脱警告,但仍然使用指针值作为布尔值。例如,您可以这样做:
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)。
然而,我同意您最好创建一个structs
数组。