It's "safe" in that the behavior is well defined. Having a function declared as accepting void *
is normal when it needs to deal with many different types of data; e.g. memcpy
.
It's not morally safe. By passing void *
you are making the compiler unable to check that the pointer you are passing points to memory that holds data in the form and quantity that you expect. It is then up to you to enforce this.
In your trivial example you can see that the objects are actually int
, and everything is fine.
In general, however, where we pass void *
to a function, we should also pass additional information describing the memory we are handing over in enough detail that the function can do its job; if we have a function that only ever deals with one type, we look long and hard at the design decisions that made us pass around void *
values instead of that type.
For sanity's sake (and, depending on the compiler, performance), please consider also marking arguments you are not writing to as const
.