Cao said:
How do I pass different types of argument such as short, int, long,
etc.. to a function that does routine stuff?
In this case you can take advantage of promotions by making the argument
a long int, so that any integral type will be accepted. Similarly, you
can use doubles for arguments that should accept any floating-point type.
In general though, the ability to write one piece of code and then use
it for many different types is a feature called *generics* that C does
not support. C++ supports these in the form of templates, and upcoming
versions of Java and C# support them. It is often possible, however, to
do one of the following:
1. Write C code that works on several types by passing a void pointer to
the object along with a type identifier:
void DoGenericThing(void* object, enum typeID) {
switch(typeID) {
case TypeShape: { Shape* shape = object; /* ... */ }
case TypeCar: {Car* car = object; /* ... */ }
case TypePresident: {President* pres = object; /* ... */ }
}
}
Once you've done this, you can enhance type safety in C99, gcc, and
other environments supporting inline functions by creating inline wrappers:
inline void DoGenericThingShape(Shape* shape) {
DoGenericThing(shape, TypeShape);
}
etc.
2. If you're simply storing the types, not executing operations on them,
as in a container of some sort, then it suffices to pass a void pointer
to the object with the size and then use memmove to move the data around.
3. Use macros with token-pasting to generate a different version of the
function for each type you wish to use it with:
#define DECLARE_DOGENERICTHING(type) \
void do_generic_thing_##type(type t);
#define DEFINE_DOGENERICTHING(type) \
void do_generic_thing_##type(type t) { \
/* Implementation */ \
}
Then use both macros in any module you want to have access to a
particular instantiation. Put the DECLARE macro in a header to export an
instantiation, so it can be reused.