jxh*_*jxh 6 c pointers void strict-aliasing language-lawyer
我想编写一个泛型函数来检测某个任意类型的指针数组是否包含a NULL
.我最初的尝试是这样的:
bool find_null (void *ptrs, size_t num_ptrs) {
void **array = ptrs;
size_t i;
for (i = 0; i < num_ptrs; ++i) {
if (array[i] == NULL) return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
有人指出,这可能会导致严格的别名冲突,因为指针数组Foo
将作为指针数组进行访问void
,但未列为允许在C.2011中访问对象的允许方式之一§ 6.57.
我可以重写函数来访问指针数组unsigned char *
,但我不知道如何在NULL
不破坏严格别名的情况下执行检查.有人可以提供有效的技术吗?
bool find_null (void *ptrs, size_t num_ptrs) {
unsigned char *array = ptrs;
void *p;
size_t i;
for (i = 0; i < num_ptrs; ++i) {
memcpy(&p, array + i * sizeof(p), sizeof(p));
if (p == NULL) return true;
/*
* Above seems to still break strict aliasing.
* What should be done instead?
*/
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
目标是编写一个与类型特定函数相同的泛型函数.换句话说,以下函数的泛型版本:
bool find_null_Foo (Foo *array[], size_t num_ptrs) {
size_t i;
for (i = 0; i < num_ptrs; ++i) {
if (array[i] == NULL) return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
您无法使用您提供的特定界面来完成此操作,但您可以通过这种有点笨拙的方式来完成此操作:
bool find_null (const void *array, size_t num_ptrs, size_t ptr_size,
const void *null) {
const char (*ptr_array)[ptr_size] = array;
size_t i;
for (i = 0; i < num_ptrs; ++i) {
if (!memcmp(array[i], null, ptr_size)) return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼它:
struct Foo;
#define ARRAY_SIZE 53
int main(void) {
struct Foo *my_array[ARRAY_SIZE] = { ... };
struct Foo * const foo_null = (struct Foo *) 0;
if (find_null(my_array, ARRAY_SIZE, sizeof(*my_array), &foo_null)) {
puts("It contains NULL");
} else {
puts("It does not contain NULL");
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,假设所讨论类型的空指针只有一种表示形式,这在许多实现中都是如此,但语言并不要求这样做。
另请注意,这实际上并不是特定于查找空指针,因此实际上您可以使用它来搜索指针数组以查找任何指针值。事实上,它甚至不是特定于指针数组的——您可以使用它来搜索任何数组中的任何值,只要字节对字节相等是一个合适的匹配标准(它不适用于结构或联合体,并且可能不适用于某些其他类型)。
此外,如果这适合您,那么您可能可以设计一个包装宏,使其更容易用于一些更常见的场景。
归档时间: |
|
查看次数: |
146 次 |
最近记录: |