Void Pointers: Difference Between C and C++

Difference between void pointers in C and C++

The value doesn't matter, the type does. Since p is a void pointer and s a char pointer, you have to cast, even if they have the same value. In C it will be ok, void* is the generic pointer, but this is incorrect in C++.

By the way, p doesn't contains char pointer, it's a void pointer and it contains a memory address.

C: what type is the difference of two void pointers?

From C11, 6.5.6 Additive operators /9 (my italics):

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header.

By that section, it's also technically undefined behaviour to subtract NULL from a pointer since NULL can in no way be considered a pointer to an element of the same array, or one beyond it. Pointer subtraction is really limited to getting the index difference between two elements in the same array.

So you may want to reconsider this checking that you're doing, especially in light of the fact a double doesn't actually need to be eight bytes long and, even if it is, there's no requirement in the standard that it be aligned on an eight-byte boundary.

I'd be more inclined to just state in the documentation for your function that the value passed needs to be a valid double pointer and, if a user of your function violates that contract, all bets are off.

void pointers: difference between C and C++

In C, pointer conversions to and from void* were always implicit.

In C++, conversions from T* to void* are implicit, but void* to anything else requires a cast.

Explain difference between the use of void pointer

The lower version tells you what the problem was in the first one: passing a pointer to the array instead of a pointer to the first element.

Passing a pointer to the array, which has the type int(*)[3]:

test(&test_array, var_1);

Passing a pointer to the first element, which has the type int*:

test(test_array, var_1);   

The code happens to work because the two pointers points to the same address, so the pointer to the array appears to work, but the code is still undefined.

Passing a pointer to the first element is correct, as the array test_array, which has the type int[3] decays to type int* when it is passed to the function.

Comparison between void pointers in C++

I'm comparing two void pointer that are pointing to the same "raw data" but with different type so different size...how it can works? Is it linked to the == operator?

That is not exactly what you are doing. You are interpreting char and int values as pointers to void. Size does not matter at all in this case.

You are nicely demonstrating one reason why not to use C-style cast - it not being clear what it is doing exactly. The rules can be found e.g. on cppreference. In your case it uses reinterpret_cast which should be a red flag had you seen it in the code in the first place.

Casting an integer to a pointer is a way how to point to specific memory address, which is far from what you want. But the comparison will most likely be true since 'a' is usually 97 (0x61). So you are effectively asking 0x61==0x61.

To answer you question

What's the size of the pointed memory by a void pointer?

, which is not related to the code you posted, it is platform-specific, most probably 4 or 8 bytes.

Difference between C++ void Pointer and C# var

The other answers here are pretty good but I think they do not get clearly to the fundamentals. It is the fundamentals you are confused about, so let's address those.

  • A variable is a storage location that contains a value.
  • A variable is associated with a type.
  • A local variable has a name.

So voidInt, voidChar, voidCharArray, varInt, varChar and varCharArray are all variables, and they all have types associated with them. Each variable can be assigned a value of that type or produce a value of that type, depending on whether the variable is being written to or read from.

OK, so now what are pointers?

  • A type has a corresponding pointer type. (Note that in unsafe C# only the unmanaged types have corresponding pointer types.)
  • The void * type is a special pointer type.
  • A pointer is a value.
  • A pointer of type T* may be dereferenced to produce a variable of type T. T* must not be void*.
  • A pointer may be explicitly converted to or from any integral type, though these operations are permitted to lose information and are dependent on implementation details.
  • Any pointer value may be implicitly converted to void*.
  • Any void* value may be explicitly converted to any pointer type value.

And what is var in C#?

  • var is a "syntactic sugar" that tells the compiler to deduce the type of the variable from the initialzier rather than requiring that it be written out.

And what are "anonymous types" in C#?

  • Some expressions in C# have a type that is not declared and has no name; these are known as the "anonymous" types.

So now we can look at your program and see what each line does.

void * voidInt = (void *) 7;

voidInt is a variable of type void*. The value assigned to it is the conversion of the integer 7 to a pointer, which is almost certainly a garbage pointer on any modern operating system. This code is essentially nonsensical.

More sensible code would be:

int myInt = 7;
int* intPtr = &myInt;
void* voidInt = intPtr;

This means that myInt is a variable which holds the value 7, intPtr is a variable which holds a pointer; when that pointer is dereferenced it produces variable myInt. voidInt is a variable which holds any pointer, and the value read from intPtr is a pointer. So now voidInt and intPtr both hold a pointer to variable myInt.

void * voidChar = (void *) 'F';

Same thing here. The character F is treated as a number and converted to a pointer value, which is stored in the variable. This is not sensible. Sensible code would be something like:

char myChar = 'F';
void *voidChar = &myChar;

But this makes perfect sense:

void * voidCharArray = (void *) "AbcString";

A string literal in C++ is convertible to a char* which is a pointer to the storage for the first character, and that pointer is convertible to void*.

What about this?

var varInt = 7;
var varChar = 'F';
var varCharArray = "AbcString";

This is just a pleasant way to write

int varInt = 7;
char varChar = 'F';
string varCharArray = "AbcString";

Each variable has its given type, and each assignment stores a value of that type in the variable.

What about anonymous types?

var anon = new { X = 123, Y = 456 };

This makes a variable of anonymous type, where the anonymous type has two properties X and Y both of type int. The type has no name, so there is no way to write out the type in the declaration, hence var must be used.

The key thing here is to make sure that you have a grasp of the fundamentals: pointers are values, they may be dereferenced, and doing so produces a variable. Since pointers are values they may themselves be stored in variables of pointer type. This has almost nothing to do with var, which is a pleasant way in C# to make the compiler do the work of figuring out what type a variable should have.

Comparing values pointed at by void pointers in C

You have to know what type of data the void pointers really point at, coerce the pointers to point to that type, and then dereference the coerced pointers (and assume that the types are comparable using ==):

if (*(int *)pi == *(int *)pj)
printf("same.\n");
else
printf("different.\n");

It's a lot easier just to compare the original variables:

if (i == j)

or to use correctly typed pointers:

int *pi = &i;
int *pj = &j;
if (*pi == *pj)


What happens in the case that I do not know the type of data (assuming that an user will always pass the same type of data to be compared with my linked list delete method)?

Then life gets difficult. Ideally you get the programmer to pass you a comparator function — see bsearch() and
qsort() from the Standard C library for examples.

Failing that, you need to know the size of the target type and you hope that memcmp() will do the job sufficiently well. That's far from guaranteed — it is not clear that comparing two double values with memcmp() will always produce the correct answer (it might claim different representations of NaN are different, for example), and comparing struct types with padding is fraught, and it wouldn't work correctly for your linked list data type if you're passed the nodes (it might be OK if you're passed the data fields from the two nodes).

If you needed to do ordering rather than just equality (a binary search tree, for example), then the situation is worse — in that case, require the programmer to supply the comparator function.

Difference Between (void *)pointer and &pointer?

(void*)ptr casts ptr to a void pointer without altering its value. &ptr, on the other hand, yields the address of the pointer itself. In other words, &ptr is a pointer to a pointer. iptr and vptr are different objects and as such they have different addresses.

Difference between void * and void **

First snippet

 foo++;//error

because, foo is pointer to void and you cannot have pointer arithmetic on void *, size of the void type is not defined.

Second snippet,

 bar++;//no error

because, bar is a pointer to a pointer to void. So, arithmetic operation is permitted, as the size of a pointer to pointer type is well defined.

FWIW, don't get surprised if sometimes, void pointer arithmetic "works" without any error.

Confused about the pointers and generic(void) pointers in C

"void*" means "this value is a pointer to something, but I'm not telling you what it points to". Start with this statement, and everything makes sense.

So it should be clear that you can't dereference a void*, because nobody told you what it points to! If you don't know whether it points to an int, a char, or some struct, what do you think should happen if you dereference it?

In C, you can assign a void* to any pointer, for example to an int*. The compiler doesn't know what the void* points to, but when you write r = p; the compiler says "I hope you know what you are doing, I trust you. " (A C++ compiler in the same situation doesn't trust you). If the void* p did indeed point to an int, everything is fine. Otherwise, things are more or less bad.

The ?? one is wrong. You can't dereference *p. Doesn't matter what you do afterwards, *p isn't allowed. And no pointer is cast to an integer. There is an attempt to dereference a pointer, which isn't allowed. The result of the dereference couldn't be anything useful since you don't know what p points to, so you have nothing useful to cast to an int.

Now what happens in * (int *) p: p is a void * - a pointer to something, but you don't know what it points to. (int * )p is a cast: p is converted to an int*. That means the compiler will believe that (int*)p points to an int - that may or may not be true. * (int * ) p dereferences the int*: So in total, you convinced the compiler that p points to an int, and to read the int that p hopefully points to. If p did actually point to an int, it's fine. If p didn't point to an int, you're in trouble.



Related Topics



Leave a reply



Submit