In C, because you often use void * for containers, there may be less code bloat than a container multiply used using generics which accessors are monomorphized for each type. In practice this is pretty trivial difference and can be bounded and understood well enough.
C is weakly typed, because you can cast or set any variable to be a void *. Since C is weakly typed, then you can write a C++ program that is also weakly typed.
void * is the C's equivalent of interface {} it has little to do with generics although it can be used to work around lack of it.
Perhaps there are other ways, but in C you have parametric polymorphism functionality through macros. That's why min() and max() are not functions but macros and they work with any type that can be compared, not just float64.
> in C, generic code is usually implemented with the runtime overhead of void pointers or function pointers.*
When performance really matters, seasoned C programmers more often write task-specific implementations or choose macro-based libraries. In this particular benchmark, the C implementation is using a macro-based hash table which does not have the penalty of void*.
C is full of implicit type conversions. I think the key is that C is based on value semantics and not references, and that makes pointers full-blown values with their own address, conversions, … - something closer to C's integer types than to other languages' references, and equally picky about operators.
Your information is very much out of date. C++ makes a few important changes that make most c code incompatible. #1, implicit cast between void and non-void pointers is not allowed, so something like:
int *x = malloc(sizeof(int) * 15)
is legal c, but in c++ you would have to cast the malloc call. Also, type of character literals is int in c but char in c++. String literals are const only in c++. Functions that take no arguments must be declared as taking void (as in void func(void)) in c, but simply () in c++.
The RAII benefits are definitely there and STL containers are pretty awesome, but you can still create generic containers in C by using void pointers. For example, a simple vector API:
typedef struct { void *elements; int elem_size; int n; } Vector;
Vector *vector_new(int elem_size);
void vector_free(Vector *v);
void vector_push(Vector *v, void *elem);
void vector_pop(Vector *v);
int vector_size(Vector *v);
void *vector_at(Vector *v, int i);
etc. This is off the top of my head, but you get the idea. You can basically put anything you want in there as long as you say how large the elements are upon initialization.
- C has broader support for designated initializers
- C allows implicitly casting void* to any other pointer type
- C has fewer keywords, e.g. you can use "friend" or "class" as identifier
- ...
Despite all this, it's true enough that one can easily write C code that also compiles as C++.
reply