Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly handling platform specifics (unix/windows) in C?

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 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?

like image 380
dlamotte Avatar asked Nov 18 '25 21:11

dlamotte


1 Answers

I think the right way to handle this is to split your code base into platform specific modules and have them assembled at build time (this of course requires some sort of platform abstraction layer.) That way your Unix code is not littered with Windows calls, and vise versa. Effectively you move your ifdef headache to the makefiles.

like image 75
Nikolai Fetissov Avatar answered Nov 20 '25 16:11

Nikolai Fetissov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!