2

I'm creating a program and I want it to run on Windows and UNIX. However I've used many functions that are either Windows or Unix specific. For example functions located in #include<unistd.h> and #include <sys/utsname.h> for UNIX and #include <winsock2.h>and #include <windows.h>for Windows. I've got them working independently but I want to merge them together.

Here is an example:

struct timespec start, end; // UNIX code
LARGE_INTEGER clockFrequency; // Windows code
QueryPerformanceFrequency(&clockFrequency); 
LARGE_INTEGER startTime; 
LARGE_INTEGER endTime; 
LARGE_INTEGER elapsedTime; 
//...
QueryPerformanceCounter(&startTime); // Windows code
clock_gettime(CLOCK_REALTIME, &start); // UNIX code
CalculateVectorInputs();
QueryPerformanceCounter(&endTime); // Windows code
clock_gettime(CLOCK_REALTIME, &end); // UNIX code

I'm well aware of ifdef:

#ifdef _WIN32
// Windows code
#else
#ifdef __unix__
// UNIX code
#endif
#endif

but this seems very messy to add all throughout my code, seeing as my program is around 500 lines long. Is there an elegant way to approach this?

asked Aug 28, 2018 at 11:44
2
  • You could create a Windows and a Linux header file with wrappers for these functions that would carry the same name, that way you only have a single ifdef and you don't need to have them everywhere? Commented Aug 28, 2018 at 11:46
  • 1
    You need to learn about abstractions and interfaces. For example, you could put the Windows-specific code in a library, and the Unix-specific code in another library, both of them having the same interface (public functions). Then on Windows build the Windows-only library and link with it, and the same for Unix platforms with the Unix-only library. Commented Aug 28, 2018 at 11:47

1 Answer 1

6

A fairly common approach is to write your main application in standard C wherever possible and put all platform specific code in a custom module.

For example, your main application could do

#include "foo_timer.h"
...
foo_timer_t start, end;
foo_get_time(&start);
calculate_stuff();
foo_get_time(&end);
foo_time_delta(start, end, &elapsed);

with no #ifdefs at all.

foo_timer.h might make use of #ifdef to select platform specific typedefs and declarations, but the main implementation will be in separate files:

  • foo_timer_unix.c contains unix-specific code that implements the foo_timer.h interface.
  • foo_timer_windows.c contains windows-specific code that implements the foo_timer.h interface.

When your application is compiled, only one of foo_timer_unix.c and foo_timer_windows.c is compiled and linked into the application. The details of this step depend on your build system.

answered Aug 28, 2018 at 11:58
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.