FWIW, C++ does force some things on you, such as automatically typedefing structs instead of giving you a separate namespace, not warning about multiple declarations with different arguments (because function overloading is a feature), not warning about multiple definitions in different compilation units (linker just picks one, assumes they are equivalent), having to cast assignment of void* to a typed pointer (ugly and redundant), slower compilation, and generally later errors/warnings (thus usually more cryptic and less useful, although it does stricter type checking in some ways, so this point is not completely clear-cut).
Hi, just want to bounce on the "cast your void to a pointer"*, actually you don't need to do that if you don't use an object oriented paradigm à la Java, but go generic full speed and use return by value. No pointers, little or no casting.
As a simple example, suppose I use malloc to allocate memory (because I don't want to allocate with new which would oblige me to handle exceptions and prevent me from handing ownership over to a C client or using an allocator provided by a C client (without extra work)). I have to cast the return value as in
which then works with a standard error checking convention
struct Foo *arr;
err = MallocA(n,&arr);CHK(err);
This doesn't work in C++ without non-portable typeof or evil and less safe (not conforming for function pointers)
*(void**)(p) = malloc((n)*sizeof(**(p)))
Similarly, if a client registers a callback with a context, I store their context in a void* and pass it back to them
int UserCallback(void *ctx,...) {
struct User *user = (struct User*)ctx;
instead of
int UserCallback(void *ctx,...) {
struct User *user = ctx;
I understand that this is just cosmetic. I don't see how "going generic full speed" helps with this. Also note that aggregate returns are slower for all but trivially small structures, and downright bad for big structures.