I was asked in an interview to how would you identify the platform only by providing runnable C code?
The code must be runnable in both platform(i.e no special header files function used to check)?
I was asked in an interview to how would you identify the platform only by providing runnable C code?
The code must be runnable in both platform(i.e no special header files function used to check)?
a quick google search shows this
#if defined(_WIN64)
/* Microsoft Windows (64-bit). ------------------------------ */
#elif defined(_WIN32)
/* Microsoft Windows (32-bit). ------------------------------ */
#endif
OS identification macros are predefined by all C/C++ compilers to enable #if/#endif sets to wrap OS-specific code. This is often necessary in cross-platform code that must use low-level library functions for fast disk I/O, inter-process communications, or threads. While differences between Windows and other OSes are acute, even differences among UNIX-style OSes can require #if/#endif constructs. This article surveys common compilers and shows how to use predefined macros to detect common OSes at compile time.
The question is wierd. You can't provide an executable which can run on multiple platforms. So the obvious answer is: compile it on one platform: if it runs, that's the platform you're on; if it doesn't you're on some other platform.
Supposing that you do have separate executables, there's really no real answer. For starters, what do you consider "a different platform"? Are Linux on a Sparc and Linux on a PC different platforms? What about two different versions of Linux? What about running under CygWin? Regardless of how you define it, though, you'll probably need a separate test for each platform. But the question is silly, because, except for considering different versions different platforms, you'll need a distinct executable for each platform, which means that you have to distinguish at compile time anyway
Just for the record: for starters, I'd use boost::filesystem,
and try to read directories "c:\\"
and "/usr"
. In theory,
you could have a directory named "c:\\"
in the current
directory under Unix, or a directory named "/usr"
in C: under
Windows, but the odds are definitely against it. Otherwise, try
various files in "/proc/myPID"
. The
directory will almost certainly not exist under Windows, and
even if it does, it won't have the dynamic structure it has
under various Unix. And the structure varies from one Unix to
the next, so you should even be able to distinguish between
Solaris and Linux.
If the comparison is just between Windows and Linux on a PC, of course, the simplest is to compile in 32 bit mode, and take the address of a local variable. If it's greater than 0x8000000, you're under Linux; if it's less, Windows.
That's a bit vague. A binary won't run in both systems unless you run under Wine (then see http://wiki.winehq.org/DeveloperFaq#detect-wine ).
At compile time you can check for #defines specific to Windows or Linux, but arguably that's compiler- and supported-Standards-specific, so I'm not sure if you're "allowed" to do that for the purposes of the interview question (i.e. it's arguably in there with your "no special header files function used to check" restriction).
In general I don't think it makes any sense to do in preference to compile-time checks, and it might not work under Wine, but you could use dlsym()
to check yourself for symbols known to be present on only one of the Operating Systems, or look at your own executable image to see what it is.
Practically, it's also very likely you can inspect your environment variables and make a pretty good determination based on that, though someone might be able to deliberately fool your program into an incorrect assessment, or your determination method might break in future versions of the Operating Systems, under different shells etc..
At run-time, you could e.g. stat("/dev", &buf)
, which should only work on Linux. Trying to popen
(3) say uname
is another plausible approach: you'll be able to read "linux\n" iff you're on Linux, while a cygwin-like environment apparently reports NT
, see here too.
Most of the common methods make the determination at compile time.
If you really insist on making the determination at run time, you could attempt to use a device (for one possibility) that exists on one but not the other (e.g., attempting to open a file named /dev/null
should work on Linux but normally fail on Windows).
Aside from the usual MACRO invocations:
#ifdef _WIN32
...
#if defined (_MSC_VER)
...
#ifdef __unix__
...
You could simply use the getenv()
function and test for some variables set like SHELL
or WINDIR
. Interesting cases to decide:
Of course, "Windows" environment variables can be set in Linux too - and vice-versa.
If you considering only the Linux platform or the Windows platform, this code will be work as needed to you on C and C++.
#include <stdio.h>
#if defined(__linux__) // any linux distribution
#define PLATFORM "linux"
#elif defined(_WIN32) // any windows system
#define PLATFORM "windows"
#else
#define PLATFORM "Is not linux or windows"
#endif
int main(int argc, char *argv[]) {
puts(PLATFORM);
return 0;
}
A full answer with an example see there https://stackoverflow.com/a/42040445/6003870
Every platform has own pre processor directive defined. You have to write the codes within it it.
How do I check OS with a preprocessor directive? Please follow above link. It may be repeated question.