简体   繁体   English

C语言按已知大小强制转换void指针

[英]C language cast void pointer by known size

Simple question, can we in c language cast void pointer by known size by unknown data type? 简单的问题,我们可以用c语言按已知大小按未知数据类型转换void指针吗?

Consider this situation: 考虑这种情况:

function assertEqual , which should get 2 pointers as arguments, dereference them and equal value. 函数assertEqual ,它应该得到2个指针作为参数,取消引用它们和相等的值。 You can't of course dereference void pointer, but what if I know size of data, which the pointer point to? 你当然不能取消引用void指针,但是如果我知道指针所指向的数据大小呢? Can I create some dynamic pointer of known size but unknown data type? 我可以创建一些已知大小但未知数据类型的动态指针吗? The function should looks like assertEqual(void* expected, void* current, size_t size) . 该函数应该看起来像assertEqual(void * expected,void * current,size_t size)

您可以将参数转换为unsigned char* ,然后比较第一个size字节(或者更好地使用memcmp来执行此操作),但不能保证在给定值有多个表示的情况下它会执行您想要的操作(例如,考虑在结构中填充,填充内容的差异可能是无害的,但是可以通过这种方法检测到,还有其他情况,例如浮点格式的NaN值,并且在技术上可能发生在最原始的情况下类型)。

Can I create some dynamic pointer of known size but unknown data type? 我可以创建一些已知大小但未知数据类型的动态指针吗?

As a general rule. 作为基本规则。 no. 没有。 You need to know the type to typecast the void pointer. 您需要知道类型以对类型指针进行类型转换。 eg float and int both have a size of 4 bytes but the types are not equivalent. 例如float和int都有4个字节的大小,但类型不相等。

However, if you have equivalent types, then you can typecast to the equivalent type. 但是,如果您具有等效类型,则可以将类型转换为等效类型。 eg on some systems int and long are both 4 bytes and are equivalent. 例如,在某些系统上,int和long都是4个字节并且是等效的。

Simple question, can we in c language cast void pointer by known size by unknown data type? 简单的问题,我们可以用c语言按已知大小按未知数据类型转换void指针吗?

No. Every pointer type has a specific type to which it points. 不可以。每个指针类型都有一个特定的类型。 That includes void * , whose referenced type ( void ), is an incomplete type provided by the language. 这包括void * ,其引用类型( void )是语言提供的不完整类型。 There is no such thing as a pointer to an unknown data type, though in void * you have a pointer type that is is interconvertible with all other object pointer types. 有一个指针,指向一个未知的数据类型,没有这样的事情,虽然在void *你有一个指针类型是可以相互转换与所有其他对象指针类型。

On the other hand, it is valid to access objects of any type via a pointer to a character type (eg char * , unsigned char * ), and one way to do that is via an lvalue whose type is an array of characters. 另一方面,通过指向字符类型的指针(例如char *unsigned char * )访问任何类型的对象是有效的,并且一种方法是通过其类型为字符数组的左值。 You could get something very similar to what you ask like so: 你可以得到与你所要求的非常相似的东西:

int assertEqual(void* expected, void* current, size_t size) {
    unsigned char (*ep)[size] = expected;
    unsigned char (*cp)[size] = current;
    // ...
}

That makes use of a variable-length array type as the pointed-to type: pointers ep and cp each point to an array of size elements of type unsigned char . 这使用了一个可变长度数组类型作为指向类型:指针epcp都指向unsigned char类型的size元素数组 The size of that array type is size , so, for example, you will indeed find that sizeof(*ep) == size . 该数组类型的sizesize ,因此,例如,您确实会发现sizeof(*ep) == size That is, you have a pointer to an object of the specified size, through which you are permitted to access the bytes of that object. 也就是说,您有一个指向指定大小的对象的指针,您可以通过该指针访问该对象的字节。

As others have already pointed out, however, what you ask is kinda pointless. 然而,正如其他人已经指出的那样,你所要求的是有点无意义的。 If you just want to compare two byte sequences without knowing what type of object they represent, then you can use memcmp() . 如果您只想比较两个字节序列而不知道它们代表什么类型的对象,那么您可以使用memcmp() On the other hand, that is not safe as a general equality test because two objects with different byte sequences can nevertheless be equal when compared as objects of a given type. 另一方面,这作为一般的相等性测试是不安全的,因为当作为给定类型的对象进行比较时,具有不同字节序列的两个对象仍然可以是相等的。 This happens because many integer types are permitted to have padding bits that do not contribute to their values, and because floating-point representations are completely implementation-dependent. 发生这种情况是因为允许许多整数类型具有不对其值有贡献的填充位,并且因为浮点表示完全取决于实现。

Furthermore, struct and union types can contain padding bytes with unspecified, and not necessarily consistent values. 此外, structunion类型可以包含未指定的填充字节,并且不一定是一致的值。 You cannot compare compound types with the == operator, but comparing the byte arrays constituting the representations of such objects does not necessarily yield the same result as would comparing the objects on a per-member basis. 您无法将复合类型与==运算符进行比较,但是比较构成此类对象的表示的字节数组不一定会产生与基于每个成员的对象进行比较相同的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM