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.
What does this mean?
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
instead of This looks purely cosmetic, but in C, I can write the macro which then works with a standard error checking convention This doesn't work in C++ without non-portable typeof or evil and less safe (not conforming for function pointers) Similarly, if a client registers a callback with a context, I store their context in a void* and pass it back to them instead of 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.