1
votes

Simple question, can we in c language cast void pointer by known size by unknown data type?

Consider this situation:

function assertEqual, which should get 2 pointers as arguments, dereference them and equal value. You can't of course dereference void pointer, but what if I know size of data, which the pointer point to? 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).

3
If you want to dereference something, you must choose a type. Equality is only defined for "known" types. - user824425
Most likely the function is a "functor" and the whole point of its existence is to provide a type-specific comparison - meaning that the function does know what type to cast to. Go read up of how the standard function bsearch works and it should all become clear. - Lundin
I don't think you mean the size of the pointers, but the size of the objects you point to. - too honest for this site

3 Answers

3
votes

You could cast the argument to unsigned char* and then compare the first size bytes (or better use memcmp which does that), but it is not guaranteed that it would do what you want in cases where there are multiple representations for a given value (think for instance to padding in a structure, a difference in the content of the padding is probably harmless but it would be detected by such an approach, there are other cases such as NaN value for floating point formats and technically that could happens for most primitive types).

0
votes

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. e.g. float and int both have a size of 4 bytes but the types are not equivalent.

However, if you have equivalent types, then you can typecast to the equivalent type. e.g. on some systems int and long are both 4 bytes and are equivalent.

0
votes

Simple question, can we in c language cast void pointer by known size by unknown data type?

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. 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.

On the other hand, it is valid to access objects of any type via a pointer to a character type (e.g. char *, unsigned char *), and one way to do that is via an lvalue whose type is an array of characters. 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. The size of that array type is size, so, for example, you will indeed find that 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(). 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. 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.