This question is intentionally very generic and I'm not much of a C programmer although I dabble here and there. The following code is intentionally vague and probably won't compile, but I hope you get the point...
Handling platform specifics seems dynamically in a compiled language like C seems unnecessary and even scary:
int main(int argc, char *argv[]) {
if (windows)
dowindowsroutine();
else
dounixroutine();
return 0;
}
However, handling platform specifics through really very basic macros seems gross too as the function gets chopped up into small pieces which may not compile properly (read answer to http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing for a similar problem).
int main(int argc, char *argv[]) {
#ifdef windows
dowindowsroutine();
#else
dounixroutine();
#endif
return 0;
}
So what's the "right" way to do this? Is it a case-by-case basis? Is there a good way to keep these gross macros out of functions entirely? I remember reading somewhere (probably in the kernel docs or something related) that macros (more importantly, complex macro logic) is meant for header files, not .c files. How do you handle this kind of stuff?
I'm sick of "spaghetti code" with ifdef's inside of functions... I spose there are some cases where it may be OK, but the majority of code I see abuse it.
Note: I've seen some perl XS code look like it wraps function prototypes to and things, but is that the only way? Isn't that somewhat gross in the community? Or is that OK? Coming from a mostly "scripted" background of perl, python, shell,... It's hard for me to tell.
Update: Let me be more clear, the problem I'm trying to avoid is that I don't want choppy code. I want to be able to ensure that if my code breaks at compile time in linux, it also breaks at compile time in windows. With the choppy code, its possible to break windows from compiling, but not linux and vice versa. Is this kind of thing possible? The closest thing to this so far is ifdef'ing the entire function, but the function names are the same, is there a better solution where there is one interface, but the OS specific parts have their OS name embedded into the name?