Hacker News new | past | comments | ask | show | jobs | submit login

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.


> go generic full speed

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

  struct Foo *x = (struct Foo*)malloc(n*sizeof(*x));
instead of

  struct Foo *x = malloc(n*sizeof(*x));
This looks purely cosmetic, but in C, I can write the macro

  #define MallocA(n,p) (!(*(p) = malloc((n)*sizeof(**(p))))
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.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: