Hi Loic,
Thank you for your prompt reply and thoughts.
Perhaps I did not clearly provide the background. Different platforms, such as Windows, Linux, BSD, and proprietary (often real time) operating systems offer a different set of include files. Also, add-on packages often provide their own set of include files.
There is often a relatively standard set of “core” include files for a platform or add-on package, but many products offer extensions and/or alternatives which can be useful to a developer. It is not unusual as software matures that new features (like a high precision time system, for example) are added. Initially, these new features may be exclusive to a platform, but as the feature gets popular (intellectual property not withstanding), these newer features become more available on different platforms. Many of these features are hardware or third party related.
Example … high precision time functions are different on Windows and Linux. Many developers, myself included, have chosen to wrap these platform-specific functions in a more generic function to provide portability across Windows and Linux with high-precision time.
An easy way to write this wrapper function is to use conditional compilation.
Example pseudo-code.
If platform A,
Include necessary unique-to-A include files
If platform B,
Include necessary unique-to-B include files
<Code which is common to both platforms >
If platform A
<code specific to A>
Else If platform B
<code specific to B>
<more common code>
…
So … how do you conditionally include a header file?
#ifdef WIN32
#include “stdafx.h”
#endif
The stdafx.h file is Windows Visual Studio specific, and does not exist on Linux. Such source will compile properly on Linux, even with full compiler-level warnings.
#ifdef WIN32
#include <windows.h>
#endif
// For Mac OS X
#if defined(__MACH__) && defined(__APPLE__)
#include <mach/mach_time.h>
// Mac OS X is native 64 bit lseeks.
#define lseek64 lseek
#define off64_t off_t
#endif
// headers for block special devices under Linux, don’t exist on Windows
#ifndef WIN32
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
//Windows and Linux have different names for low-level data types,
// often used by low-level C-compatible OS “system” functions.
// The Linux environment does not define LPVOID by default
#ifndef WIN32
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
Yes, you could refactor and create smaller platform-specific source files with the proper header includes, without needing conditional compilation. But then you need conditional linking to ensure that the proper sub-routine gets liked in.
Also … it is often advantageous to have the different flavors of similar platform-specific features near each other in the same source file …. rather than in separate source files. In this way, it is easier to understand that the code segments are indeed working the same way.
There are many other examples. In the early days of POSIX …. Many developers wanted to use the more-standardized POSIX forms of functions (such as threads), rather than the “native” thread functions. So you would conditionally test for POSIX, and include the POSIX headers if available, and include the “native” headers otherwise.
In my case … this is the typical reason I use conditionally included header files … to support Linux, MacOS, BSD, and in some cases, Windows in the same source.
So …. Without a mechanism to tell the SonarLint to ignore a missing include file in the next line, I will always get lint errors from SonarLint.
Regards,
Dave B