我有两种数据类型,它们具有不同大小的同名字段。我试图根据我传入函数的参数来访问这些字段---比如说
struct smallindex
{
unsigned char index;
unsigned int count;
};
struct largeindex
{
unsigned int index;
unsigned long count;
};
这可能不是理想的事情 - 但实现这一点的一种方法是让函数将指针视为不同大小的指针。比如说:
void function(int index, void *ptr)
{
array[] = {struct smallindex, struct largeindex};
array[index] *pointer = *ptr;
*pointer[1].index++;
return;
}
然而,编译器完全不喜欢这个。我尝试了其他几个实现 - 但是没有一个实现。位域大小的可变性使我无法尝试联合。这可行吗?
或者,如果我填充索引大小以确保它们的大小匹配(但它们的字段位置仍然不匹配) - 那么这可行吗?
答案 0 :(得分:2)
在函数内部,您可以将ptr
转换为类型char *
或int *
,或指向结构或联合类型的指针,但每个指针都指向一种类型。如果结果无法与指针类型正确对齐,则此类转换会产生未定义的行为,但在转换为ptr
实际指向的对象类型时不会发生这种情况。
此外,您可以通过字符类型指针(char *
,unsigned char *
等)自由访问任何对象表示的字节。但是,如果尝试通过指向不同,不兼容类型的对象的指针来访问对象,则会产生未定义的行为。访问指向对象是将指针转换为不同指针类型的单独考虑因素。
因此,您可以这样做:
void function(int index, void *ptr) {
// treat `ptr` as pointing to the first element of an array of int
int *pointer = ptr;
pointer[index]++; // UB here if ptr really points to something other than int
}
和此:
void function(int index, void *ptr) {
// treat `ptr` as pointing to the first element of an array of char
char *pointer = ptr;
pointer[index]++;
}
甚至这个:
void function(int index, void *ptr, _Bool is_int_ptr) {
// Treat ptr as pointing to char or int depending on the value of is_int_ptr
if (is_int_ptr) {
int *pointer = ptr;
pointer[index]++;
} else {
char *pointer = ptr;
pointer[index]++;
}
}
但指针值本身并不包含它指向哪种类型的信息。您需要一种机制来告诉程序它指向哪种类型。通常,这将通过函数参数的声明类型(使该函数特定于该类型),但您可以通过单独的参数传达它,如上例所示。