Mark Summerfield <
mark@qtrac.eu> wrote or quoted:
I want a generic (int/str/custom struct) set, map, ordered map, vector.
C is a stripped-down language designed to get close to
the hardware with minimal overhead. It skips many of the
high-level features in C++, like templates, classes, and
operator overloading. Trying to make C act like C++ by
building a generic container library can lead to:
Complexity: Creating generic containers in C often means
dealing with gnarly macros, void pointers, and type casting,
which can make the code a pain to read and maintain.
Inefficiency: Generic containers in C might not be as slick
as those in C++ due to the lack of compile-time type checking
and optimizations. And,
error-prone code: Without the type safety provided by C++ templates,
generic containers in C are more likely to cause runtime errors.
Idiomatic C programming rolls with the language's strengths and
works within its constraints. This often involves:
Explicit typing: C programmers usually define data structures
and functions explicitly for each type they need, rather
than leaning on generic solutions.
Manual memory management: C programmers are used to managing
memory by hand, which can be more predictable and efficient than
relying on a generic container library. And,
simplicity and clarity: C code is often straightforward and simple,
focusing on clear and direct solutions rather than abstract
and generalized ones.
The old pros of C came up with several techniques to handle the
lack of generic containers:
Structs and pointers: Using structs and pointers to create
custom data structures tailored to specific needs.
Function pointers: Employing function pointers to pull off a form
of polymorphism. And,
Macros: Utilizing preprocessor macros to create reusable code
snippets, though this can lead to less readable and maintainable code
if overdone.
Some problems encountered when using generic container libraries
in C might be:
portability: Generic container libraries in C can be less portable
across different compilers and platforms.
Debugging: Debugging generic code in C can be more of a
hassle due to the lack of type information and the use of
void pointers. And,
performance: Hand-crafted, type-specific data structures
and algorithms can often be more performant than generic
implementations.
While it's technically possible to whip up a generic container
library in C, doing so often goes against the grain of
idiomatic C programming.
C shines in simplicity, explicitness, and low-level control.
Embracing these traits leads to more maintainable, efficient, and
understandable code. Instead of trying to force C to act like C++,
it's generally better to leverage C's strengths and use techniques
that are well-suited to the language's design and philosophy.