在为Apache Web服务器构建模块时,我遇到了几个实例,其中结构声明表明它只需要const char*
成员apr_table_t
和apr_array_header_t
,但我在mod_security等各种模块中找到的示例,甚至新的ap_parse_form_data
函数都表明正在将void *
数据类型插入到这些结构中。
我的问题是这怎么可能?为什么我的Visual Studio编译器会抱怨如果我尝试使用相同的方法?
一个很好的例子是mod_security,它有一个create_request函数,可以在void *
注释中存储request_rec
。
答案 0 :(得分:1)
指针是 convertible ,并且每个对象指针类型都可以转换为void*
,因为在void*
中存储任何指针都不会丢失信息。也就是说,以下内容有效:
struct Foo a;
struct Foo * p = &a; // p points to a
void * q = p; // OK, can store the value of p in q
struct Foo * r = q; // OK too - we can go back, and r points to a
r->n = 1;
因此,在C中习惯于将指针作为void*
传递,知道那些可以始终保存任何其他对象指针值,并且只在需要时将其强制转换为所需类型
关于char
指针的最后一句话:将任何对象指针强制转换为char*
并将其实际解除引用作为指向字符数组的指针 not 构成了类型惩罚,并且不违反严格别名规则 - 这只是允许您访问任何对象的基础二进制表示。